【发布时间】:2014-02-08 08:14:30
【问题描述】:
IEEE-754 算法能否在不同平台上重现?
我正在测试一些用 R 编写的使用随机数的代码。我认为在所有测试平台上设置随机数生成器的种子将使测试可重现,但对于rexp() 似乎并非如此,它生成指数分布的随机数。
这是我在 32 位 Linux 上得到的:
options(digits=22) ; set.seed(9) ; rexp(1, 5)
# [1] 0.2806184054728815824298
sessionInfo()
# R version 3.0.2 (2013-09-25)
# Platform: i686-pc-linux-gnu (32-bit)
这就是我在 64 位 OSX 10.9 上得到的:
options(digits=22) ; set.seed(9) ; rexp(1, 5)
# [1] 0.2806184054728815269186
sessionInfo()
# R version 3.0.2 (2013-09-25)
# Platform: x86_64-apple-darwin10.8.0 (64-bit)
64 位 Linux 提供与 64 位 OSX 相同的结果,因此这似乎是 32 位与 64 位的问题。
让我们假设两个 R 版本都使用相同的 GCC 版本进行编译,并且使用相同的(默认 R)编译标志,使编译器使用 IEEE-754 算法。
我的问题是,这可以被认为是 R 中的错误吗?还是只是使用近似的有限精度浮点运算的“正常”结果?
我向 R-devel 邮件列表发送了同样的问题,但在列表中没有得到任何答案,而且只有一个私下的答案,试图让我相信这不是一个错误,我应该忍受它。
这是 IEEE-754 关于再现性的说法(来自维基百科):
IEEE 754-1985 允许多种实现方式(例如 某些值的编码和某些异常的检测)。 IEEE 754-2008 已收紧其中许多,但有一些变化 仍然存在(尤其是二进制格式)。再现性 条款建议语言标准应提供一种手段 编写可重现的程序(即,将产生相同的程序 导致一种语言的所有实现),并描述了需要什么 以达到可重复的结果。
这是在“建议”下。
我的(主观)意见是这是一个错误,因为 IEEE-754 标准的重点在于具有可重现的、独立于平台的浮点运算。
【问题讨论】:
-
digits=22超出了您的机器限制;请参阅.Machine$double.eps,它提前大约六位数结束。 -
@DirkEddelbuettel 我不确定这是否重要,IEEE-754 的建议是“提供一种编写可重现程序的方法”。例如。如果它可以重现 16 位数字,但不能重现,那么 R 应该在那里截断。我的问题不是操作不准确,那很好。问题是相同的代码给出不同的结果。 IEEE-754 允许你犯错。但它建议你总是以同样的方式犯错。
-
也许关于如何截断的最佳实践确实有用。我很满意
set.seed(42); print(runif(3), digits=16)在 i386、x86_64 和我的 Android 手机(后者运行 free R Console app)上给我相同的结果。 -
是的,它实际上不是 RNG(可能),而是从统一的随机数创建一个指数分布的随机数。这并不奇怪,AFAIK RNG 通常是整数算术。但是指数是浮点运算。这就是为什么
runif()很好。
标签: r floating-point ieee-754