当进行非常大的计算时,模量精度完全丧失

问题描述 投票:2回答:3

我有以下问题:

> 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 modulus largenumber integer-arithmetic
3个回答
5
投票

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

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

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


3
投票

要对大于64b的数量实施精确整数运算,可以选择:

  1. 使用任意精度的软件包,例如gmp或类似的see "Multiplication of large integers in R"或...
  2. 进一步了解您的“模块化计算器”挑战的精神,请以对大整数的准确性为准的思想来实施算术运算。 (请向我们显示您使用的确切输入表达式以及您的代码)

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

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


1
投票

我只需要更改:

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

进入:

terms[2:length(terms)] %<>%
    str_c("x <<- gmp::as.bigz(x) ", .)
© www.soinside.com 2019 - 2024. All rights reserved.