当在R中输入1e9999999999999999999999999999999
时,R挂起并且不会响应-需要终止它。
它似乎发生在3台不同的计算机上,操作系统(Windows 7和Ubuntu)。它发生在RStudio,RGui和RScript中。
下面是一些更容易生成数字的代码:
boom <- paste(c("1e", rep(9, 31)), collapse="")
eval(parse(text=boom))
很明显,这不是一个实际问题,我没有必要用这么大的数字,这只是一个好奇心的问题。
奇怪的是,如果你尝试1e9999999999999999999999999999998
或1e10000000000000000000000000000000
(乘方加1或减1),你会得到Inf
和0
,这个数字显然是某种边界,但是在什么和为什么之间呢?
我认为它可能是:
- 一个浮点问题,但我认为他们最大值为1.7977e308,远远早于问题中的数字。
- 32位整数的问题,但是2^32是4294967296,比所讨论的数字小得多。
- 很奇怪。这是我的主流理论。
编辑:最迟截至2015-09-15,这不再导致R挂起,他们一定打了补丁。
4条答案
按热度按时间k97glaaz1#
这看起来像是解析器中的一个极端情况。
XeY
在第10.3.1节中描述:R Language Definition的文字常量,指向?NumericConstants
以获取“当前接受格式的最新信息”。问题似乎出在解析器如何处理指数,数字常量由
NumericValue
处理(main/gram.c
的第4361行),它调用mkFloat
(main/gram.c
的第4124行),R_atof
调用main/util.c
的第1584行),R_atof
调用R_strtod4
(main/util.c
的第1461行)。(所有这些操作都是从修订版60052开始的。)main/utils.c
的第1464行显示expn
声明为int
,如果指数太大,它将在第1551行溢出。有符号整数溢出导致未定义的行为。例如,下面的代码为指数〈308左右生成值,为指数〉308生成
Inf
。您可以看到指数〉2^31时的未定义行为(指数= 2^31时R挂起):
我怀疑这会引起R-core的注意,因为R只能存储大约2 e-308到2 e +308之间的数值(参见
?double
),而这个数字远远超过了这个数字。368yc8dk2#
这很有趣,但我认为R在解析指数非常大的数字时存在系统性问题:
好了,终于有合理的解释了。根据这个输出和约书亚Ulrich下面的注解,R似乎支持表示最大为2e308的数字和解析指数最大为+2 ×10^9的数字,但它不能表示它们。在那之后,显然由于溢出而有未定义的行为。
vfh0ocws3#
1e9999999999999999999999999999999
是某个阈值,或者解析例程阅读指数的缓冲区有限。您的观察结果与32个字符(以空结尾)的指数缓冲区一致。我宁愿在论坛或邮件列表上问这个问题,据说这是友好的。
或者,由于 R 是自由软件,您可以研究它的源代码。
cunj1qz14#
R有时可能会使用bignums。也许1e999999999999999999999999999是某个阈值,或者也许解析例程有一个有限的缓冲区来阅读指数。您的观察结果将与32个字符(以空结尾)的指数缓冲区一致。
我宁愿在R的论坛或邮件列表上问这个问题,据说这些论坛或邮件列表很友好。
或者,由于R是自由软件,您可以研究它的源代码。