问题
我多次被告知,如果运算的数字接近 1.0
(或有时 0.1
),浮点运算的精度最高。这有什么道理吗?
澄清
“算术”是指 a + b
、a * b
、a/b
,还有 sqrt (x)
和其他数学函数。
具体来说,假设所有变量都是IEEE 64 bit double precision float 。
例子
在物理模拟代码中,物理单位通常通过将它们映射到浮点值来合并。在这里我们有很多自由,但一个选择是使用 SI/metric system , 像
# Base units
m = 1.0 # metre
s = 1.0 # second
kg = 1.0 # kilogram
# Derived units
km = 1e+3*m # kilometre
yr = 60*60*24*365.25*s # year
m_sun = 1.98841e+30*kg # mass of the sun
c = 299792458*m/s # speed of light
...
此类代码中任何量纲变量的数值取决于单位系统的选择。如果我们得到一个值 x == 1.2e-9
并且 x
应该被理解为例如长度,我们知道这意味着 x
是 1.2 纳米。如果我们选择设置 m = 1e-9
,x
将取而代之的是 1.2
的值,因为我们现在正在纳米为基本长度单位的单位制。
根据模拟中研究的物理系统,可能会选择不同的“自然”单位系统。如果我们的重点是原子物理学,那么选择太阳质量作为基本质量单位可能并不理想。为什么不呢?那是我的问题。当然,所有感兴趣的质量都会有很小的数值,但那又怎样?浮点运算固有的不精确性是否会因处理极小/极大的数字而以某种方式被放大?
我知道存在最小和最大 float (类似于 1e-324
和 1e+308
)。对于手头的任务使用如此古怪的单位系统,以至于我们的变量值超出这些限制当然是破坏性的。尽管将值很好地保持在这些范围内,代码中的典型值是否顺序为 1.0
、1e±10
、1e±100< 真的有什么区别吗
?
关于数学函数的注意事项
在输入非常大/非常小的情况下,各种数学函数实际上明显不精确。例如,cos(1e-8) == 1
,即cos()
函数无法区分小于1e-8
的正数.这与我的问题不相关,因为 cos()
的输入必须始终是无量纲的纯数字,即独立于代码中定义的单位系统。这同样适用于所有其他三角函数,还有 exp()
、log()
和其他函数。
最佳答案
Is floating point math more precise for values close to unity?
不是真的。
一般来说, float 学很好地保留了*
、/
、sqrt()
覆盖的真实精度浮点范围的最大份额。 +
、-
由于减去附近的值而导致相对精度(对结果)的显着损失。
总体而言,相对 精度的正常数字几乎没有差异。它从 (0.5 到 1.0] * 2-53 变化。
绝对精度以 2 的幂为单位变化。
float [0.5...1.0) 具有相同的绝对精度。对于 double
2-54。
float [1.0...2.0) 具有相同的绝对精度。对于 double
2-53。
float [2.0...4.0) 具有相同的绝对精度。对于 double
2-52。
float [4.0...8.0) 具有相同的绝对精度。对于 double
2-51。
等等
floating point arithmetic has the greatest precision if the numbers operated on are close to 1.0 (or sometimes 0.1). Is there any truth to this?
刚好低于 2 的幂的值比刚好高于 2 的幂的值具有更高的绝对精度(大约 2 倍)。
对于微小的次正常值,精度会丢失,每 2 次幂一位,直到达到 0.0。
高级:当三角函数的量级很大时,需要特别注意三角函数。高质量的 sin(1e10)
对主要的 [-pi ... pi] 范围进行内部扩展的高精度参数缩减。并非所有触发函数实现都能很好地处理此步骤。因此,对于弧度参数,从主要范围开始有助于保持精度。对于度数参数,一个简单的 fmod(deg, 360.0)
是一个简单而精确的范围缩减。
关于floating-point - 对于接近统一的值, float 学是否更精确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64285399/