Огромная разница.
Как следует из названия, a double
имеет 2-кратную точность [1] . В общем случае a имеет 15 десятичных знаков точности, а имеет 7.float
double
float
Вот как рассчитывается количество цифр:
double
имеет 52 бита мантиссы + 1 скрытый бит: log (2 53 ) ÷ log (10) = 15,95 цифр
float
имеет 23 бита мантиссы + 1 скрытый бит: log (2 24 ) ÷ log (10) = 7,22 цифры
Эта потеря точности может привести к увеличению ошибок усечения при повторных вычислениях, например
float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.7g\n", b); // prints 9.000023
пока
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.15g\n", b); // prints 8.99999999999996
Кроме того, максимальное значение с плавающей точкой составляет около 3e38
, но двойное около 1.7e308
, поэтому использование float
может достигнуть «бесконечности» (то есть специального числа с плавающей запятой) гораздо легче, чем double
для чего-то простого, например, для вычисления факториала 60.
Во время тестирования, возможно, несколько тестовых примеров содержат эти огромные числа, которые могут вызвать сбой ваших программ, если вы используете плавающие числа.
Конечно, иногда даже double
не достаточно точно, поэтому у нас иногда есть long double
[1] (приведенный выше пример дает 9.000000000000000066 на Mac), но все типы с плавающей запятой страдают от ошибок округления , поэтому, если точность очень важна (например, деньги) обработки) вы должны использовать int
или класс дроби.
Кроме того, не используйте +=
для суммирования много чисел с плавающей запятой, так как ошибки быстро накапливаются. Если вы используете Python, используйте fsum
. В противном случае попробуйте реализовать алгоритм суммирования Кахана .
[1]: С и С ++ стандарты не определяют отображение float
, double
и long double
. Вполне возможно, что все три реализованы как IEEE двойной точности. Тем не менее, для большинства архитектур (GCC, MSVC; x86, x64, ARM) float
является действительно IEEE одинарной точности с плавающей запятой (binary32), и double
это IEEE двойной точности с плавающей запятой (binary64).