输入1e9999999999999999999999999999999
时进入 R,R 挂起并且不会响应 - 需要将其终止。
这似乎发生在 3 台不同的计算机、操作系统(Windows 7 和 Ubuntu)上。它发生在 RStudio、RGui 和 RScript 中。
这里有一些代码可以更轻松地生成数字:
boom <- paste(c("1e", rep(9, 31)), collapse="")
eval(parse(text=boom))
现在显然这不是一个实际问题。我不需要使用这么大的数字。这只是好奇心的问题。
奇怪的是,如果你尝试 1e9999999999999999999999999999998
或1e10000000000000000000000000000000
(幂加或减一),你得到 Inf
和0
分别。这个数字显然是某种边界,但是什么和为什么在这里?
我认为可能是:
- 浮点问题,但我认为它们的最大值为 1.7977e308,远早于相关数字。
- 32 位整数存在问题,但 2^32 是 4294967296,比有问题的数字小得多。
- 真的很奇怪。这是我的主导理论。
编辑:最晚从 2015 年 9 月 15 日起,这不再导致 R 挂起。他们一定已经修补了它。
最佳答案
这看起来像是解析器中的一个极端情况。 XeY
格式在Section 10.3.1: Literal Constants中描述。 R Language Definition的并指向?NumericConstants
了解“当前接受格式的最新信息”。
问题似乎在于解析器如何处理指数。数字常量由 NumericValue
处理( main/gram.c
的第 4361 行),它调用 mkFloat
( main/gram.c
的第 4124 行),它调用 R_atof
( main/util.c
的第 1584 行),它调用 R_strtod4
(main/util.c
的第 1461 行)。 (全部自修订版 60052 起。)
main/utils.c
的第1464行显示expn
声明为int
如果指数太大就会在第1551行溢出。有符号整数溢出会导致未定义的行为。
例如,下面的代码生成指数 < 308 左右和 Inf
的值对于指数 > 308。
const <- paste0("1e",2^(1:31)-2)
for(n in const) print(eval(parse(text=n)))
您可以看到指数 > 2^31 的未定义行为(R 在指数 = 2^31 时挂起):
const <- paste0("1e",2^(31:61)+1)
for(n in const) print(eval(parse(text=n)))
我怀疑这会引起 R-core 的任何关注,因为 R 只能存储大约 2e-308 到 2e+308 之间的数值(请参阅 ?double
),而这个数字远远超出了这个范围.
关于r - 为什么数字 1e9999...(31 个 9)会在 R 中引起问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11700748/