R中浮点精度的极端数字值

16

有人能解释一下以下的输出吗?我知道它与浮点精度有关,但数量级(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

4
好的,这是R FAQ 7.31 - user3710546
2
特别是,请尝试 options(digits = 22); x <- 1 - 1e-16; y <- 1 - 1e-17 == 1; print(y); print(x) - Robert Krzyzanowski
@DavidArenburg 我不认为你所提供的“重复”问题完全相同。OP似乎并没有说他们对某个值必须被完全表示感到惊讶,而是关于在0附近和1附近可表示数字的密度。 - Pascal Cuoq
2
@DavidArenburg,你是指那个拥有金徽章的Roman用户吗?他没有阅读评论或查找真正的重复问题,就关闭了这个问题?这个问题交给专业人士处理。 - Pascal Cuoq
1
@user3710546:公平地说,R FAQ 7.31中所示的数字示例非常糟糕;它没有加法示例,因此无法说明任何.Machine$ulp,eps,min.exp,xmin(1 - 1e-17 == 1) == TRUE是一个更清晰、更简单的例子。 - smci
显示剩余5条评论
2个回答

16

R使用IEEE 754双精度浮点数。

浮点数在靠近零时更密集。这是因为它们被设计为能够在非常宽的范围内准确计算(相当于大约16个有效数字),如您所注意到的。

也许您期望一个具有均匀绝对精度的定点系统。实际上,定点要么浪费空间,要么必须事先仔细估计每个中间计算的范围,如果估计错误会产生严重后果。

正浮点数的示意图如下:

+-+-+-+--+--+--+----+----+----+--------+--------+--------+--
0

最小正常双精度数是2的最小指数次幂。接近1时,双精度浮点数已经相当分散。从1到其下一个数的距离是2的-53次方,而从1到其上一个数的距离是2的-52次方。


如果支持完整的17位精度,几乎17个有效数字 - 1-1e-17将与1不同。 - Patricia Shanahan
@PatriciaShanahan 我想表达的是,十进制数字的数量只是二进制浮点数精度的粗略度量,并最终使用了“等效”,这并不够强。我已经添加了“大约”。 - Pascal Cuoq
2
在我们吹毛求疵的时候,“近16位数字”比“近17位数字”更准确(2^53大约是10^15.95)。 - Mark Dickinson

9
根据@PascalCuoq的回答,由于IEEE 754兼容平台(例如x86)上R双精度浮点数的精度不完全是16位小数:
# 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,并被舍入为浮点数1.0。
请参阅R文档的 .Machine:“机器的数字特征”。特别关注EPS和ULP之间的差异。
(ULP是相对于FP数字1定义的。你的FP数字越大,最后一位的值就越大,舍入操作就越粗糙)
至于数量1e-323来自哪里:你将ULP与可表示的最小FP值混淆了,后者要小得多。
根据IEEE 754双精度示例可表示的最小正规化FP值的指数为e-308...
# 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...

如果使用未标准化的浮点数,即所有前导尾数位都为0,我们可以得到稍微更小的值。因此,正如您从经验上发现的那样,最小可表示的未标准化正浮点值在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在舍入之前内部带有一些保护数字。
另请注意参数,该参数表示表示法是基于2的:.Machine$double.base = 2

4
对于所有的投票者和读者,请真正评论一下有什么问题,如果有的话。我为这篇文章付出了一些努力。 - smci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接