在“F# for Scientists”中,Jon Harrop 说:
Roughly speaking, values of type int approximate real numbers between min-int and max-int with a constant absolute error of +- 1/2 whereas values of the type float have an approximately-constant relative error that is a tiny fraction of a percent.
现在,这是什么意思? int 类型不准确?
为什么 C# for (1 - 0.9) 返回 0.1 而 F# 返回 0.099999999999978? C#更准确更适合科学计算吗?
我们应该使用十进制值而不是 double / float 进行科学计算吗?
最佳答案
对于任意实数,整数类型或浮点类型都只能提供近似值。积分近似在一个方向或另一个方向上的偏差永远不会超过 0.5(假设实数符合该积分类型的范围)。 float 近似值的偏差永远不会超过一小部分(同样,假设实数在该浮点类型支持的值范围内)。这意味着对于较小的值,浮点类型将提供更接近的近似值(例如,将 PI 的近似值存储在 float 中将比 int 近似值 3 更准确)。然而,对于非常大的值,整数类型的近似值实际上会比浮点类型的近似值更好(例如,考虑值 9223372036854775806.7,当表示为 9223372036854775807 为 long 时,它仅相差 0.3,但当存储为 9223372036854780000.000000 时,它表示为 9223372036854780000.000000一个 float )。
这只是您如何打印值的人工产物。 9/10 和 1/10 不能精确地表示为浮点值(因为分母不是 2 的幂),就像 1/3 不能精确地写成小数一样(你得到 0.333... 其中3 永远重复)。无论您使用哪种 .NET 语言,此值的内部表示都将相同,但打印值的不同方式可能会以不同方式显示它。请注意,如果您在 FSI 中评估 1.0 - 0.9,结果将显示为 0.1(至少在我的计算机上是这样)。
您在科学计算中使用哪种类型取决于您想要实现的目标。您的回答通常只会大致准确。您需要它有多准确?您的性能要求是什么?我认为 decimal 类型实际上是一个定点数,这可能使其不适合涉及非常小或非常大的值的计算。另请注意,F# 包括任意精度有理数(具有 BigNum 类型),这也可能适用于您的输入。
关于f# - F#(和 .NET)中的浮点精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/713439/