小编典典

float似乎double有什么区别?

all

我已经阅读了float似乎double之间的区别。然而,在大多数情况下,float似乎double是可以互换的,即使用其中一种似乎不会影响结果。真的是这样吗?浮点数和双精度数何时可以互换?它们之间有什么区别?


阅读 169

收藏
2022-03-13

共1个答案

小编典典

巨大的差异。

顾名思义, adouble的精度是[1]的 2 倍。一般来说,a有 15 位精度,而有 7
位。floatdouble``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

此外,float 的最大值约为3e38,但 double
约为1.7e308,因此使用float可以比简单的计算更容易达到“无穷大”(即特殊的浮点数)double,例如计算 60 的阶乘。

在测试过程中,可能有几个测试用例包含这些巨大的数字,如果您使用浮点数,可能会导致您的程序失败。


当然,有时,甚至double不够准确,因此我们有时有long double[1](上面的示例在 Mac 上给出
9.000000000000000066),但所有浮点类型都会 出现舍入误差 ,所以如果精度非常重要(例如金钱处理)你应该使用int或分数类。


此外,不要使用+=对大量浮点数求和,因为错误会迅速累积。如果您使用的是 Python,请使用fsum. 否则,尝试实现Kahan
求和算法


[1]:C 和 C++ 标准没有指定 和的float表示。有可能所有三个都实现为 IEEE
双精度。尽管如此,对于大多数架构(gcc、MSVC;x86、x64、ARM) 来说 确实是一个 IEEE 单精度浮点数(binary32),并且
一个 IEEE 双精度浮点数(binary64)。double``long double``float double

2022-03-13