float 和 double 有什么区别?

35 浏览
0 Comments

float 和 double 有什么区别?

我已经读到过双精度和单精度之间的差异。但在大多数情况下,floatdouble似乎可以互换使用,即使用其中之一似乎不会影响结果。这真的是这样吗?什么情况下可以互换使用float和double?它们之间有什么区别?

admin 更改状态以发布 2023年5月21日
0
0 Comments

以下是标准 C99 (ISO-IEC 9899 6.2.5 §10) 或 C++2003 (ISO-IEC 14882-2003 3.1.9 §8) 所述:

有三种浮点类型:floatdoublelong double。类型double提供了至少与float一样多的精度,而类型long double提供了至少与double一样多的精度。类型float的值集是类型double的值集的一个子集;类型double的值集是类型long double的值集的一个子集。

C++标准补充说:

浮点类型的值表示是由实现定义的。

我建议看看优秀的计算机科学家应该了解的浮点算术知识,深入探讨IEEE浮点标准。你会了解到表示细节,并意识到精度和数量之间存在权衡。浮点表示的精度随数量的减少而增加,因此-1到1之间的浮点数具有最高的精度。

0
0 Comments

巨大的差异。

正如其名称所示,doublefloat精度高2倍[1]。通常,double的精度为15个小数位,而float的精度为7个。

以下是数字位数的计算方法:

double有52位隐含位数+1位隐藏位数:log(253)÷log(10) = 15.95位小数

float有23位隐含位数+1位隐藏位数:log(224)÷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,因此在计算简单的事情(例如计算60的阶乘)时,使用float可以更容易地达到"无穷大"(即一种特殊的浮点数)。

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


当然,有时候,即使是double也不够准确,因此我们有时会使用long double[1](例如上面的例子在Mac上给出的结果是9.000000000000000066),但所有浮点数类型都会受到舍入误差的影响,因此如果精度非常重要(例如处理货币),应该使用int或分数类。


此外,不要使用+=来求和大量浮点数,因为误差会快速累积。如果你在使用Python,可以使用fsum。否则,尝试实现Kahan求和算法


[1]:C和C++标准没有规定floatdoublelong double的表示方式。三者都可能被实现为IEEE double-precision。然而,对于大多数体系结构(如gcc,MSVC;x86,x64,ARM),float确实是IEEE single-precision浮点数(binary32),而double是IEEE double-precision浮点数(binary64)。

0