r - 为什么数字 1e9999...(31 个 9)会在 R 中引起问题?

标签 r

输入1e9999999999999999999999999999999时进入 R,R 挂起并且不会响应 - 需要将其终止。

这似乎发生在 3 台不同的计算机、操作系统(Windows 7 和 Ubuntu)上。它发生在 RStudio、RGui 和 RScript 中。

这里有一些代码可以更轻松地生成数字:

boom <- paste(c("1e", rep(9, 31)), collapse="")
eval(parse(text=boom))

现在显然这不是一个实际问题。我不需要使用这么大的数字。这只是好奇心的问题。

奇怪的是,如果你尝试 1e99999999999999999999999999999981e10000000000000000000000000000000 (幂加或减一),你得到 Inf0分别。这个数字显然是某种边界,但是什么和为什么在这里?

我认为可能是:

  • 浮点问题,但我认为它们的最大值为 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/

相关文章:

R - 如何对比代码因素并在输出摘要中保留有意义的标签

r - 使用 R 上的官员包在 pptx 上使用多种格式的文本

r - ggplot geom_smooth 排除负值

R 错误 : Shadow graphics device error

sql - 在 R 或 SQL 中分桶

r - 更改稀疏相关矩阵的图形表示

r - 如何找到至少2个向量中常见的元素?

r - 如何在数据表的每一行上有效地应用可归约函数

R:在 R 中使用亚洲/中文字符创建 n 元语法?

r - 如何删除多面 R ggplot 箱线图中未使用的因素?