浮点数和双精度数有什么区别?

新手上路,请多包涵

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

原文由 VaioIsBorn 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

巨大的差异。

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

以下是位数的计算方式:

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 可以达到“无穷大”(即一个特殊的浮点数) number) 比 double 对于一些简单的事情要容易得多,例如计算 60 的阶乘。

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


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


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


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

原文由 kennytm 发布,翻译遵循 CC BY-SA 4.0 许可协议

从数量上讲,正如其他答案所指出的那样,区别在于类型 double 的精度大约是 --- 类型的两倍,范围是其 float (取决于您的计数方式)。

但也许更重要的是质的差异。类型 float 具有良好的精度,无论您在做什么,这通常都足够好。另一方面,类型 double 具有 出色 的精度,无论您在做什么,它几乎总是足够好。

结果并不像它应该的那样广为人知, 你应该几乎总是使用类型 double 。除非你有一些特别的需要,你几乎不应该使用类型 float

众所周知,在进行浮点运算时,“舍入误差”通常是一个问题。舍入误差可能很微妙,难以追踪,也难以修复。大多数程序员没有时间或专业知识来追踪和修复浮点算法中的数值错误——因为不幸的是,每种不同算法的细节最终都会有所不同。但是类型 double 具有足够的精度,因此在很多时候,您不必担心。无论如何你都会得到好的结果。另一方面,对于 float 类型,四舍五入的令人担忧的问题总是 会出现

类型 floatdouble 之间 不一定 不同的是执行速度。在当今的大多数通用处理器上,对 floatdouble 类型的算术运算所花费的时间或多或少完全相同。一切都是并行完成的,因此您无需为 double 类型的更大范围和精度支付速度损失。这就是为什么建议您几乎不应该使用类型 float 是安全的:使用 double 不应该在速度上花费你任何东西,也不应该在空间上花费你太多,并且几乎肯定会在精度和舍入误差问题的自由中获得丰厚的回报。

(话虽如此,您可能需要类型 float 的“特殊需求”之一是当您在微控制器上进行嵌入式工作或编写针对 GPU 优化的代码时。在那些处理器上, 类型 double 可能会慢很多,或者实际上不存在,因此在这些情况下,程序员通常会选择类型 float 以提高速度,并且可能会以精度为代价。)

原文由 Steve Summit 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题