11

我正在研究 R 中数值运算的极端情况。我遇到了以下涉及零除以零的特殊情况:

(0/0)+NA
#> [1] NaN
NA+(0/0)
#> [1] NA

reprex 包于 2021-07-10 创建 (v2.0.0 )

会话信息
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

这显然违反了加法的交换性。我有两个问题:

  1. 是否有基于 R 语言定义的这种行为的解释?

  2. 是否有其他违反加法交换属性的示例(包括其他语言),不涉及 addend 子表达式中的副作用?

4

2 回答 2

12

注意到

0/0
#[1] NaN

问题中的行为的更一般示例+如下:

NA + NaN
#[1] NA
 
NaN + NA
#[1] NaN

这是在一个r-devel 线程中,R 核心团队成员Tomas Kalibera 回答了以下问题(我的重点和链接)。

是的,在 R 级别修复此问题的性能开销太大,并且会使代码显着复杂化。涉及 NA 和 NaN 的二进制操作的结果取决于硬件(NaN 有效载荷的传播)——在某些硬件上,它实际上按照我们想要的方式工作——返回 NA——但在某些硬件上你会得到 NaN 或有时是 NA 有时是 NaN . 还有 C 编译器优化重新排序代码,如 ?NaN 中所述。然后还有不区分 NA 和 NaN 的外部数值库(NA 是一个 R 概念)。所以我担心这是无法修复的。邓肯提到的免责声明在 ?NaN/?NA 中,我认为这没问题 - 有很多数值函数可能会遇到这些问题,因此无法将它们全部记录下来。有些函数实际上会保留 NA,我们不会让 NA 不必要地变成 NaN,但免责声明说它是不依赖的。

于 2021-07-10T22:29:30.023 回答
8

?NA, 这可能是NaN由于0/0

使用 NA 的数值计算通常会导致 NA:一个可能的例外是也涉及到 NaN,在这种情况下可能会导致任何结果(这可能取决于 R 平台)。但是,这并不能保证,未来的 CPU 和/或编译器可能会有不同的行为。动态二进制转换也可能会影响这种行为(使用 valgrind,即使不涉及 NaN,使用 NA 的计算也可能导致 NaN)。

于 2021-07-10T21:43:14.350 回答