问题描述
我正在研究 R 中数值运算的极端情况。我遇到了以下涉及零除以零的特殊情况:
(0/0)+NA
#> [1] NaN
NA+(0/0)
#> [1] NA
由 reprex package (v2.0.0) 于 2021 年 7 月 10 日创建
会话信息sessionInfo()
#> R version 4.1.0 (2021-05-18)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Big Sur 10.16
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
#>
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> attached base packages:
#> [1] stats graphics Grdevices utils datasets methods base
#>
#> loaded via a namespace (and not attached):
#> [1] digest_0.6.27 withr_2.4.2 magrittr_2.0.1 reprex_2.0.0
#> [5] evaluate_0.14 highr_0.9 stringi_1.6.2 rlang_0.4.11
#> [9] cli_3.0.0 rstudioapi_0.13 fs_1.5.0 rmarkdown_2.9
#> [13] tools_4.1.0 stringr_1.4.0 glue_1.4.2 xfun_0.23
#> [17] yaml_2.2.1 compiler_4.1.0 htmltools_0.5.1.1 knitr_1.33
这显然违反了加法的交换性质。我有两个问题:
解决方法
注意
0/0
#[1] NaN
问题中 +
行为的更一般示例如下:
NA + NaN
#[1] NA
NaN + NA
#[1] NaN
这是在 r-devel thread 和 R 核心团队成员 Tomas Kalibera answers the following 中(我的重点和链接)。
是的,在 R 级别修复此问题的性能开销太大 大,它会使代码显着复杂化。 结果 涉及 NA 和 NaN 的二元运算依赖于硬件( NaN 有效载荷的传播) - 在某些硬件上,它实际上是有效的 我们希望的方式 - 返回 NA - 但在某些硬件上你会得到 NaN 或 有时是 NA 有时是 NaN。还有 C 编译器优化 重新排序代码,如 ?NaN 中所述。然后还有外部 不区分 NA 和 NaN 的数值库(NA 是一个 R 概念)。 所以恐怕这是无法修复的。 disclaimer mentioned by Duncan 在 ?NaN/?NA 中,我认为这没问题 - 有这么多数字 通过这些功能,人们可能会遇到这些问题 将它们全部记录下来是不可行的。 有些功能实际上会保留 NA,我们不会让 NA 不必要地变成 NaN,但是 免责声明说这是不值得依赖的东西。
,根据?NA
,这可能是因为NaN
来自0/0
使用 NA 的数值计算通常会导致 NA:一个可能的例外是 NaN 也涉及,在这种情况下可能会导致(这可能取决于 R 平台)。但是,这并不能保证,未来的 CPU 和/或编译器的行为可能会有所不同。动态二进制转换也可能影响这种行为(使用 valgrind,即使不涉及 NaN,使用 NA 的计算也可能导致 NaN)。