c++ - float 和 double 有什么区别?

标签 c++ c floating-point precision ieee-754

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

最佳答案

巨大的差异。

顾名思义,double精度是 float 的 2 倍[1]。一般来说,double 有 15 位精度,而 float 有 7。

位数的计算方法如下:

double has 52 mantissa bits + 1 hidden bit: log(253)÷log(10) = 15.95 digits

float has 23 mantissa bits + 1 hidden bit: log(224)÷log(10) = 7.22 digits

这种精度损失可能会导致在重复计算时累积更大的截断误差,例如

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可以达到“无穷大” (即一个特殊的 float )比 double 更容易做一些简单的事情,例如计算 60 的阶乘。

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


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


此外,不要使用 += 对大量 float 求和,因为错误会迅速累积。如果您使用的是 Python,请使用 fsum。否则,尝试执行 Kahan summation algorithm .


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

关于c++ - float 和 double 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2386772/

相关文章:

c - 数组和指针的区别

c++ - 如何在 C++11 constexpr 中检查 double 的位模式是 0x0?

c# - 在 C# 中除法以获得精确值

python - 为什么 9007199254740993 != 9007199254740993.0?

c++11可变参数模板方法完全影子基类方法?

c++ - 将字符串发送到 Arduino 的最佳方式?

c++ - 关于返回对不存在数据的引用的设计

c# - Windows 中文件的全局唯一 ID

C - 何时使用指针算术,何时使用数组索引?

c - 如果 Bison 规则中存在递归,如何决定何时更改状态?