R中的long/bigint/decimal等效数据类型

har*_*dsv 28 types r

我们有什么数据类型选择来处理R中的大数?默认情况下,整数的大小似乎是32位,因此来自sql server的bigint数字以及从python通过rpy2传递的任何大数字都会被破坏.

> 123456789123
[1] 123456789123
> 1234567891234
[1] 1.234568e+12
Run Code Online (Sandbox Code Playgroud)

当使用RODBC读取bigint值123456789123456789时,它返回为123456789123456784(参见最后一位数字),并且通过RJSONIO反序列化时的相同数字将返回-1395630315L(这似乎是RJSONIO的附加错误/限制).

> fromJSON('[1234567891]')
[1] 1234567891
> fromJSON('[12345678912]')
[1] -539222976
Run Code Online (Sandbox Code Playgroud)

其实,我需要能够处理大量来自JSON的到来,所以用RJSONIO的限制,我可能不会有一个解决办法,除了找到更好的JSON库(这似乎是一个非选项现在).我想听听专家们对此以及一般情况的看法.

dou*_*oug 23

我理解你的问题与我之前发布的两个人有点不同.

如果R的最大默认值对你来说不够大,你有几个选择(免责声明:我使用了下面提到的每个库,但不是通过R绑定,而是通过其他语言绑定或本机库)

大人国包:使用自然日志存储值; (比如Rmpfr,使用R的新类结构实现).我总是对那些工作需要这种规模的人印象深刻.

library(Brobdingnag)

googol <- as.brob(1e100)   
Run Code Online (Sandbox Code Playgroud)

GMP包,R绑定古老的GMP(GNU多精度库).这必须追溯到20年,因为我在大学使用它.这个图书馆的座右铭是"算术无限制",这是一个可信的主张 - 整数,有理数,浮点数等等,直到你盒子上RAM的极限.

library(gmp)

x = as.bigq(8000, 21)
Run Code Online (Sandbox Code Playgroud)

Rmpfr包,R绑定哪个接口都GMP(上图)和MPFR,(MPFR又一个当代实施GMP的我已经使用了Python绑定("bigfloat"),并强烈推荐它,这可能是你最好的.考虑到它的范围,三者的选择,因为它似乎是最积极维护的,并且最终给出了最全面的文档.

注意:要使用后两者中的任何一个,您需要安装本机库,GMPMPFR.


Dir*_*tel 20

help(integer):

 Note that on almost all implementations of R the range of
 representable integers is restricted to about +/-2*10^9: ‘double’s
 can hold much larger integers exactly.
Run Code Online (Sandbox Code Playgroud)

所以我建议使用numeric(即'double') - 一个双精度数字.


Mat*_*wle 17

在提出这个问题之后,现在可以获得Romain Francois的int64JensOehlschlägel的bit64.

  • 看起来 int64 现在已经消失了 (2认同)
  • @evolvedmicrobe 我们在 data.table 中使用 bit64,它运行良好 (2认同)

Sha*_*ane 8

德克是对的.您应该使用numeric类型(应该设置为double).另外需要注意的是,您可能无法取回所有数字.查看数字设置:

> options("digits")
$digits
[1] 7
Run Code Online (Sandbox Code Playgroud)

你可以扩展这个:

options(digits=14)
Run Code Online (Sandbox Code Playgroud)

或者,您可以重新格式化数字:

format(big.int, digits=14)
Run Code Online (Sandbox Code Playgroud)

我测试了你的号码并且得到了相同的行为(即使使用double数据类型),所以这可能是一个错误:

> as.double("123456789123456789")
[1] 123456789123456784
> class(as.double("123456789123456789"))
[1] "numeric"
> is.double(as.double("123456789123456789"))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)