使用gmp和机器限制的大整数

时间:2013-02-11 18:14:12

标签: r memory gmp bigint mpfr

我想知道是否可以在R中使用大于.Machine$double.xmax~1.79e308)值的整数。我认为通过使用例如R中的Rmpfrgmp库可以分配任意大小的值,最高可达系统的RAM限制吗?我认为这比.Machine$double.xmax大,但显然不是。> require( gmp ) > as.bigz( .Machine$double.xmax ) Big Integer ('bigz') : [1] 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368 > as.bigz( 1e309 ) Big Integer ('bigz') : [1] NA >

{{1}}

有人可以解释为什么使用64位内存寻址的计算机无法存储大于1.79e308的值吗?对不起 - 我没有计算机科学背景,但我正在努力学习。

感谢。

1 个答案:

答案 0 :(得分:3)

Rmpfr可以使用mpfr_set_str ...

进行字符串转换
val <- mpfr("1e309")

## 1 'mpfr' number of precision  17   bits 
## [1] 9.999997e308

# set a precision (assume base 10)...
est_prec <- function(e) floor( e/log10(2) ) + 1

val <- mpfr("1e309", est_prec(309) )

## 1 'mpfr' number of precision  1027   bits 
## [1]1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

.mpfr2bigz(val)

## Big Integer ('bigz') :
## [1] 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

# extract exponent from a scientific notation string
get_exp <- function( sci ) as.numeric( gsub("^.*e",'', sci) )

# Put it together
sci2bigz <- function( str ) {
  .mpfr2bigz( mpfr( str, est_prec( get_exp( str ) ) ) )
}

val <- sci2bigz( paste0( format( Const("pi", 1027) ), "e309") )

identical( val, .mpfr2bigz( Const("pi",1027)*mpfr(10,1027)^309 ) )

## [1] TRUE

## Big Integer ('bigz') :
## [1] 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587004

至于存储大于.Machine$double.xmax的数字的原因,IEEE规范中的浮点编码文档,R常见问题解答和维基百科都涉及所有术语,但我发现定义它很有帮助条款(使用?'.Machine')......

double.xmax(最大标准化浮点数)=
(1 - double.neg.eps) * double.base ^ double.max.exp其中

  1. double.neg.eps(一个小的正浮点数x,使1 - x!= 1)= double.base ^ double.neg.ulp.digits其中
    • double.neg.ulp.digits =最大的负整数,例如1 - double.base ^ i != 1
  2. double.max.exp = double.base溢出的最小正功率
  3. double.base(浮点表示的基数)= 2(二进制)。
  4. 根据有限浮点数与另一个有区别的思考; IEEE规范告诉我们,对于二进制64位数字11位用于指数,所以我们有一个最大指数2^(11-1)-1=1023但是我们想要溢出的最大指数所以{{1}是1024.

    double.max.exp