当计算非常大的数字时,模数的准确性完全丧失

Complete loss of accuracy in modulus when calculating with very large numbers

我有以下问题:

> 1e20 %% 3
[1] 0
Warning message:
probable complete loss of accuracy in modulus 

结果可能不正确,我敢肯定这是因为 1e20 确实很大。但是我想在R中解决这样的计算。有机会想出这个吗?

编辑: 我想做以下挑战: https://www.codeabbey.com/index/task_view/modular-calculator

这是我的代码:

library(tidyverse)
library(magrittr)

get_result <- function(.string){

  terms <- .string %>% 
    str_split("\n") %>%
    unlist %>% 
    str_replace("%", "%%") %>% 
    str_squish

  terms[1] %<>% 
    str_c("x <<- ", .)

  terms[2:length(terms)] %<>%
    str_c("x <<- x ", .)

    map(terms, ~ {
      eval(parse(text = .x))      
      })

    x

}

get_result("6
+ 12
           * 99
           + 5224
           * 53
           * 2608
           * 4920
           + 48
           + 7
           * 54
           * 4074
           + 76
           * 2
           * 97
           + 4440
           + 3
           * 130
           + 432
           * 50
           * 1
           + 933
           + 3888
           + 600
           + 9634
           * 10
           * 59
           + 62
           * 358
           + 82
           + 1685
           * 78
           + 8
           * 266
           * 256
           * 26
           * 793
           + 1248
           * 746
           * 135
           * 10
           * 184
           + 4
           * 502
           * 60
           + 9047
           * 5
           + 416
           * 7
           * 6287
           * 8
           % 4185")

在我想使用模数之前,使用真实测试数据我得到了一个巨大的数字

您的数字对于 R 的数字数据类型来说太大了。请参阅 this answer,它解释了如何查看可以用数字类型表示的最小值和最大值。它大约是 53 位,您的数字 1e20 超过了它。

另请参阅 CRAN 的常见问题解答 (section 7.31),其中更多地解释了 R 中的浮点表示。

关于如何在 R 中处理大数,请查看 this blog post 中描述的 "gmp" 包,可能对您有所帮助。

要对大于 64b 的数量执行精确的整数运算,可以:

  1. 使用任意精度的包,例如gmp 或类似 see "Multiplication of large integers in R" 或...
  2. 更本着您 'Modular Calculator' 挑战的精神,实现算术运算时考虑大整数的精确性。 (请向我们展示您使用的确切输入表达式,以及您的代码)

您想对大整数(> 64 位)进行整数运算吗?关于 'modulus' 的警告仅指 %%/modulo 运算符,而不是所有算术。 log_2(1e20) = 66.43 位,因此根据定义,如果您尝试将其存储为 64b 整数,它将丢失低位。

更新:请给我们一个实际的 MCVE 示例,其中包含您用来获得 1e20 的输入作为中间结果。他们给出的表达式((5+3)*7+10)*2*3 +1只有397.

我只需要更改:

terms[2:length(terms)] %<>%
    str_c("x <<- x ", .)

进入:

terms[2:length(terms)] %<>%
    str_c("x <<- gmp::as.bigz(x) ", .)