我已经阅读了双精度和单精度之间的区别。然而,在大多数情况下, float
和 double
似乎可以互换,即使用其中一个似乎不会影响结果。真的是这样吗?浮点数和双精度数何时可以互换?它们之间有什么区别?
原文由 VaioIsBorn 发布,翻译遵循 CC BY-SA 4.0 许可协议
我已经阅读了双精度和单精度之间的区别。然而,在大多数情况下, float
和 double
似乎可以互换,即使用其中一个似乎不会影响结果。真的是这样吗?浮点数和双精度数何时可以互换?它们之间有什么区别?
原文由 VaioIsBorn 发布,翻译遵循 CC BY-SA 4.0 许可协议
从数量上讲,正如其他答案所指出的那样,区别在于类型 double
的精度大约是 --- 类型的两倍,范围是其 float
(取决于您的计数方式)。
但也许更重要的是质的差异。类型 float
具有良好的精度,无论您在做什么,这通常都足够好。另一方面,类型 double
具有 出色 的精度,无论您在做什么,它几乎总是足够好。
结果并不像它应该的那样广为人知, 你应该几乎总是使用类型 double
。除非你有一些特别的需要,你几乎不应该使用类型 float
。
众所周知,在进行浮点运算时,“舍入误差”通常是一个问题。舍入误差可能很微妙,难以追踪,也难以修复。大多数程序员没有时间或专业知识来追踪和修复浮点算法中的数值错误——因为不幸的是,每种不同算法的细节最终都会有所不同。但是类型 double
具有足够的精度,因此在很多时候,您不必担心。无论如何你都会得到好的结果。另一方面,对于 float
类型,四舍五入的令人担忧的问题总是 会出现。
类型 float
和 double
之间 不一定 不同的是执行速度。在当今的大多数通用处理器上,对 float
和 double
类型的算术运算所花费的时间或多或少完全相同。一切都是并行完成的,因此您无需为 double
类型的更大范围和精度支付速度损失。这就是为什么建议您几乎不应该使用类型 float
是安全的:使用 double
不应该在速度上花费你任何东西,也不应该在空间上花费你太多,并且几乎肯定会在精度和舍入误差问题的自由中获得丰厚的回报。
(话虽如此,您可能需要类型 float
的“特殊需求”之一是当您在微控制器上进行嵌入式工作或编写针对 GPU 优化的代码时。在那些处理器上, 类型 double
可能会慢很多,或者实际上不存在,因此在这些情况下,程序员通常会选择类型 float
以提高速度,并且可能会以精度为代价。)
原文由 Steve Summit 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
巨大的差异。
顾名思义,
double
的精度是float
[1]的 2 倍。一般来说double
有 15 位十进制精度,而float
有 7 位。以下是位数的计算方式:
这种精度损失可能导致在重复计算时累积更大的截断误差,例如
尽管
此外,float 的最大值约为
3e38
,但 double 约为1.7e308
,因此使用float
可以达到“无穷大”(即一个特殊的浮点数) number) 比double
对于一些简单的事情要容易得多,例如计算 60 的阶乘。在测试过程中,可能有一些测试用例包含这些巨大的数字,如果使用浮点数,可能会导致程序失败。
当然,有时,即使是
double
也不够准确,因此我们有时会有long double
[1] (上面的例子在 Mac 上给出了 9.000000000000000066),但是所有浮点类型都会受到 _舍入错误_,因此如果精度非常重要(例如货币处理),您应该使用int
或分数类。此外,不要使用
+=
对大量浮点数求和,因为错误会迅速累积。如果您使用的是 Python,请使用fsum
。否则,尝试实现 Kahan 求和算法。[1]:C 和 C++ 标准没有指定
float
、double
和long double
的表示。有可能所有三个都实现为 IEEE 双精度。尽管如此,对于大多数架构(gcc、MSVC;x86、x64、ARM)来说,float
确实 是一个 IEEE 单精度浮点数(binary32),而double
是 一个 IEEE 双精度浮点数精度浮点数(binary64)。