Несоответствия с двойным типом данных в C ++ - PullRequest
1 голос
/ 24 января 2011

Это может быть что-то действительно простое, что я просто упускаю, однако у меня возникают проблемы с использованием типа данных double. здесь гласит, что двойное число в C ++ с точностью ~ 15 цифр.Тем не менее в коде:

double n = pow(2,1000);
cout << fixed << setprecision(0) << n << endl;

n хранится точное значение 2 ^ 1000, то есть, что составляет 302 десятичных знака в соответствии с WolframAlpha.Тем не менее, когда я пытаюсь вычислить 100 !, с помощью функции:

   double factorial(int number)
{
    double product = 1.0;
    for (int i = 1; i <= number; i++){product*=i;}
    return product;
}

Неточности начинают появляться на 16-й цифре.Может кто-нибудь объяснить, пожалуйста, это поведение, а также предоставить мне какое-то решение.

Спасибо

Ответы [ 3 ]

4 голосов
/ 24 января 2011

В конечном итоге вам понадобится прочитать основы в Что должен знать каждый учёный-компьютерщик об арифметике с плавающей точкой .Наиболее распространенным стандартом для оборудования с плавающей запятой обычно является IEEE 754;текущая версия выпущена в 2008 году, но большинство процессоров не поддерживают новую десятичную арифметику, представленную в выпуске 2008 года.

Однако число с плавающей запятой (double или float) сохраняет приближение к значению, используя мантиссу фиксированного размера (дробная часть) и показатель степени (степень 2).Динамический диапазон экспонент таков, что значения, которые могут быть представлены, находятся в диапазоне от 10 -300 до 10 + 300 в десятичном виде с приблизительно 16 значащими (десятичными) цифрами точности,Люди постоянно пытаются напечатать больше цифр, чем может быть сохранено, и получают интересные и машинно-зависимые (и библиотечно-зависимые) результаты, когда они это делают.

Итак, то, что вы видите, присуще природе плавающихточечная арифметика на компьютерах с использованием значений с фиксированной точностью.Если вам нужна большая точность, вам нужно использовать одну из библиотек произвольной точности - их много.

4 голосов
/ 24 января 2011

Двойник фактически хранит показатель, который будет применен к 2 во внутреннем представлении. Так что, конечно, он может хранить 2 ^ 1000 точно. Но попробуйте добавить 1 к этому.

2 голосов
/ 24 января 2011

IEEE 754 дает алгоритм для хранения данных с плавающей запятой. Компьютеры имеют конечное число бит для хранения бесконечного числа чисел и, следовательно, вносят ошибку при сохранении цифр.

В этой форме представления меньше места для точности, чем больше представленное число (больше == абсолютное расстояние от нуля). Вероятно, в этот момент вы видите потерю точности, и по мере того, как вы получаете еще большие числа, потеря точности будет еще больше.

...