对于接近统一的值,浮点数学是否更精确?
Is floating point math more precise for values close to unity?
问题
有人多次告诉我,如果运算的数字接近 1.0
(有时 0.1
),浮点运算的精度最高。这有什么道理吗?
澄清
“算术”是指 a + b
、a * b
、a / b
,还有 sqrt(x)
和其他数学函数。
具体来说,假设所有变量都是IEEE 64 bit double precision浮点数。
例子
在物理模拟代码中,物理单位通常通过将它们映射到浮点值来合并。在这里我们有很多自由,但一个选择是使用 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
的值,因为我们现在使用纳米是基本长度单位的单位系统。
根据模拟中研究的物理系统,可能会选择不同的“自然”单位系统。如果我们的重点是原子物理学,那么选择太阳质量作为基本质量单位可能并不理想。为什么不呢?那是我的问题。当然,所有感兴趣的质量都会有很小的数值,但那又怎样?使用极度 small/large 的数字是否会以某种方式放大浮点运算固有的不精确性?
我知道存在最小和最大浮点数(类似于 1e-324
和 1e+308
)。对于手头的任务使用如此古怪的单位系统,以至于我们的变量值超出这些限制当然是破坏性的。尽管将值保持在这些范围内,但代码中的典型值是否按 1.0
、1e±10
、1e±100
?
顺序真的有什么区别吗
关于数学函数的注意事项
在非常 large/small 输入的情况下,各种数学函数实际上明显不精确。例如cos(1e-8) == 1
,即cos()
函数无法区分小于1e-8
的正数。这与我的问题 不 相关,因为 cos()
的输入必须始终是无量纲的纯数字,即独立于代码中定义的单位系统。这同样适用于所有其他三角函数,还有 exp()
、log()
和其他函数。
Is floating point math more precise for values close to unity?
不是真的。
一般来说,浮点数学很好地保持了 真实 的精度 *
、/
、sqrt()
覆盖了大部分的浮动点范围。 +
、-
由于减去附近的值而导致相对精度(对结果)的显着损失。
总体而言,相对 精度的正常数字几乎没有差异。它从 (0.5 到 1.0] * 2-53.
变化
绝对精度按 2 的幂变化。
浮点数 [0.5...1.0) 具有相同的绝对精度。对于double
2-54.
浮点数 [1.0...2.0) 具有相同的绝对精度。对于double
2-53.
浮点数 [2.0...4.0) 具有相同的绝对精度。对于double
2-52.
浮点数 [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?
刚好低于 power-of-2 的值比刚好高于 2 的幂的值具有更高的绝对精度(大约 2 倍)。
使用微小的次正常 值,精度会丢失,每 2 次幂一位,直到达到 0.0。
高级:Trig 函数在其量级很大时特别值得关注。高质量 sin(1e10)
对主要 [-pi ... pi] 范围进行内部扩展高精度参数缩减。并非所有触发函数实现都能很好地处理此步骤。因此,对于弧度参数,从主要范围开始有助于保持精度。对于度参数,简单的 fmod(deg, 360.0)
是简单而精确的范围缩减。
问题
有人多次告诉我,如果运算的数字接近 1.0
(有时 0.1
),浮点运算的精度最高。这有什么道理吗?
澄清
“算术”是指 a + b
、a * b
、a / b
,还有 sqrt(x)
和其他数学函数。
具体来说,假设所有变量都是IEEE 64 bit double precision浮点数。
例子
在物理模拟代码中,物理单位通常通过将它们映射到浮点值来合并。在这里我们有很多自由,但一个选择是使用 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
的值,因为我们现在使用纳米是基本长度单位的单位系统。
根据模拟中研究的物理系统,可能会选择不同的“自然”单位系统。如果我们的重点是原子物理学,那么选择太阳质量作为基本质量单位可能并不理想。为什么不呢?那是我的问题。当然,所有感兴趣的质量都会有很小的数值,但那又怎样?使用极度 small/large 的数字是否会以某种方式放大浮点运算固有的不精确性?
我知道存在最小和最大浮点数(类似于 1e-324
和 1e+308
)。对于手头的任务使用如此古怪的单位系统,以至于我们的变量值超出这些限制当然是破坏性的。尽管将值保持在这些范围内,但代码中的典型值是否按 1.0
、1e±10
、1e±100
?
关于数学函数的注意事项
在非常 large/small 输入的情况下,各种数学函数实际上明显不精确。例如cos(1e-8) == 1
,即cos()
函数无法区分小于1e-8
的正数。这与我的问题 不 相关,因为 cos()
的输入必须始终是无量纲的纯数字,即独立于代码中定义的单位系统。这同样适用于所有其他三角函数,还有 exp()
、log()
和其他函数。
Is floating point math more precise for values close to unity?
不是真的。
一般来说,浮点数学很好地保持了 真实 的精度 *
、/
、sqrt()
覆盖了大部分的浮动点范围。 +
、-
由于减去附近的值而导致相对精度(对结果)的显着损失。
总体而言,相对 精度的正常数字几乎没有差异。它从 (0.5 到 1.0] * 2-53.
变化绝对精度按 2 的幂变化。
浮点数 [0.5...1.0) 具有相同的绝对精度。对于double
2-54.
浮点数 [1.0...2.0) 具有相同的绝对精度。对于double
2-53.
浮点数 [2.0...4.0) 具有相同的绝对精度。对于double
2-52.
浮点数 [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?
刚好低于 power-of-2 的值比刚好高于 2 的幂的值具有更高的绝对精度(大约 2 倍)。
使用微小的次正常 值,精度会丢失,每 2 次幂一位,直到达到 0.0。
高级:Trig 函数在其量级很大时特别值得关注。高质量 sin(1e10)
对主要 [-pi ... pi] 范围进行内部扩展高精度参数缩减。并非所有触发函数实现都能很好地处理此步骤。因此,对于弧度参数,从主要范围开始有助于保持精度。对于度参数,简单的 fmod(deg, 360.0)
是简单而精确的范围缩减。