有人可以解释一下以下输出。我知道它与浮点精度有关,但是magnitue(差异1e308)的顺序让我感到惊讶。
0:高精度
> 1e-324==0
[1] TRUE
> 1e-323==0
[1] FALSE
1:非常不高兴
> 1 - 1e-16 == 1
[1] FALSE
> 1 - 1e-17 == 1
[1] TRUE
答案 0 :(得分:13)
R使用IEEE 754双精度浮点数。
浮点数在零附近更密集。这是因为它们被设计为在很宽的范围内准确计算(相当于大约16个有效小数位,正如您所注意到的)。
也许你期望一个具有统一绝对精度的定点系统。在实践中,定点要么是浪费,要么必须事先仔细估算每个中间计算的范围,如果它们是错误的,会产生严重的后果。
正浮点数如下所示:
+-+-+-+--+--+--+----+----+----+--------+--------+--------+-- 0
最小正常双精度数是最小指数幂的2。接近一,双精度浮点数已经相当广泛地分布。 2 -53 的距离从1到1以下,距离2 -52 从1到它之上的数字。
答案 1 :(得分:8)
根据@ PascalCuoq的回答,因为符合IEEE 754标准的平台(例如x86)上的R double的FP精度不是十六位十进制数字:
# Machine ULP in decimal digits...
.Machine$double.ulp.digits * log10(2)
-15.65...
# Note the direct relationship between ULP digits and EPS:
.Machine$double.ulp.digits = -52
2.22 e-16 = .Machine$double.eps == 2^.Machine$double.ulp.digits
因此1 - 1e-16
已经非常接近ULP,1 - 1e-17
超出了ULP,并且四舍五入到FP 1.0
请参阅.Machine : "Numerical Characteristics of the Machine"的R文档。特别要注意EPS和ULP之间的区别。
(ULP由FP编号1定义。您的FP编号越大,最后一位的值越大,舍入操作越粗糙)
关于数量1e-323来自何处:你将ULP与最小可表示的FP值混淆,后者远小于此。
最小可表示的标准化正值FP值具有指数e-308,根据IEEE 754 Double-precision examples ...
# Minimum-representable normalized positive FP value is...
.Machine$double.xmin
2.225..e-308
# ...which would correspond to this base-2 exponent...
log10(.Machine$double.xmin) / log10(2)
-1022
# ...or this base-10 exponent...
.Machine$double.min.exp * log10(2)
-307.65...
但是如果我们使用非标准化的FP数,即所有前导尾数位都为0,我们可以稍微小一些。因此,根据经验发现,最小可表示的非标准化正FP值介于1e-324之间和1e-323 。那是因为我们有52个尾数位,因此LSB的数值是2 ^ 51或10 ^ 15.35更小:
# Exponent of Minimum-representable UNnormalized positive FP value
log10(.Machine$double.xmin) - (.Machine$double.digits * log10(2))
-323.607...
(为什么我们不能凭经验发现它?因为IEEE-754在四舍五入之前内部带有一些保护数字)
(另请注意表示表示为base-2的参数:.Machine$double.base = 2
)