У меня проблема с хранением 10 ^ 18 как с плавающей точкой - PullRequest
0 голосов
/ 26 октября 2019

Я пишу программу, которая должна принимать целое число N в диапазоне 3 <= N <= 10 ^ 18. Это одна из операций, которые я должен выполнить с N. </p>

final=((0.5*(pow(2,0.5))*(pow((pow(((N/2)-0.5),2)+pow((N/2)-0.5,2)),0.5)))-0.5)*4;

N таков, что final гарантированно содержит целое число.

Проблема в том, что я могуне храните N в типе float, так как он слишком большой. Если я сохраню его в long long int, ответ будет неправильным (я думаю, что это потому, что промежуточное значение N / 2 затем округляется).

Ответы [ 2 ]

2 голосов
/ 26 октября 2019

Правильный ответ:

final = 2 * abs(N-1) - 2;           

Это можно проверить, удалив ненужные скобки, перегруппировав одинаковые термины, распределив умножение на константы и используя следующие тождества:

Это почти такой же, как принятый ответ. Но другой ответ верен только для любых N >= 1. Это неправильно, как только N-1<0, поэтому в диапазоне возможных значений N, разрешенных вашим вопросом, для 0 <= N < 1

Вы можете проверить это с помощью этой онлайн-демонстрации

Редактировать: После того как вы отредактируете вопрос, который изменит диапазон и тем самым исключит проблемные значения, будет принят принятый ответ. Я оставляю здесь свой ответ для записей и ради математики; -)

1 голос
/ 26 октября 2019

Эта формула выглядит пугающе, но ее можно упростить (если N > 1) до

final = 4 * (N / 2 - 1)

, используя идентификатор: (x<sup>a</sup>)<sup>1/a</sup> = x.

Если предполагается, что N / 2деление с плавающей запятой, а не целое, ответ

final = 2 * (N - 2)
...