当计算非常大的数字时,模数的准确性完全丧失
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 的数量执行精确的整数运算,可以:
- 使用任意精度的包,例如
gmp
或类似 see "Multiplication of large integers in R" 或...
- 更本着您 '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) ", .)
我有以下问题:
> 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 的数量执行精确的整数运算,可以:
- 使用任意精度的包,例如
gmp
或类似 see "Multiplication of large integers in R" 或... - 更本着您 '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) ", .)