是什么决定了Ruby中整数的长度?

时间:2019-08-04 03:49:11

标签: ruby

我一直想知道Integer到达Float :: INFINITY之前的最大长度是多少。

在我的64位(Arch Linux)系统上:

> 1023.**(3355446).bit_length
# => 33549731

> 1023.**(3355446).+(1000000 ** 1000000).+(1000 ** 100).bit_length
# => 33549731

事实上:

> a = 1023.**(3355446) ; ''
# => ""

> b = 1023.**(3355446).+(1000000 ** 1000000).+(1000 ** 100) ; ''
# => ""

> a.to_s.length == b.to_s.length
# => true

上面的过程需要一些时间,但是这不需要

a, b, length_of = 1023.**(3355446), 1023.**(3355446).+(1000000 ** 1000000).+(1000 ** 100), lambda { |x| Math.log10(x).to_i.next } ; ''
# => ""

length_of.(a).eql?(length_of.(b))
# => true

因此,如果您正在运行一个程序,该程序具有无限循环,并且计数器每秒增加数百或数千次,并且您必须以24 * 365的速度运行它,那可能会导致错误。

>

那么问题是什么决定了Ruby中Integer的长度?在32位和64位系统上是否有所不同?

编辑:

在我的rapsberry pi 3模型B上:

2.**(31580669).bit_length
# => 31580670

2.**(31580669).next.bit_length
# => 31580670

> l = ->(x) { Math.log10(x).to_i.next }
# => #<Proc:0x00a46df0@(irb):1 (lambda)>

> l === 2.**(31580669)
# => 9506729

> l === 2.**(31580669) + 100 ** 100
# => 9506729

因此,在Ruby 2.3及更早版本上的问题将是Bignum有多大。从Ruby 2.4+开始,问题是整数可以有多大?

1 个答案:

答案 0 :(得分:2)

  

Integer到达Float :: INFINITY之前的最大长度是多少。

Ruby中的整数操作将(几乎)永远不会返回Infinity。一个整数可以和您拥有的内存一样大。

Float被实现为经典的double precision-floating point number,其上限大约为1.7976931348623623157e + 308,如果走高将返回Float::Infinity

1.7976931348623157e+308.to_f + 10**307
 => Infinity 

某些语言(例如Perl 5)将整数升级为双精度,以获取更多的工作空间。因此,如果高度过高,您将获得Infinity。

$ perl -wle 'printf "%f\n", 10**308'
100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000
$ perl -wle 'printf "%f\n", 10**308 + 10**308'
Inf

但是Ruby的Integer没有限制,只有您的记忆。当Integer太大时,他们会切换为使用支持GNU Multiple Precision Arithmetic Libraryarbitrary precision arithmetic

有一些操作会导致无穷大,例如功率。

10**10000000
(irb):5: warning: in a**b, b may be too big
 => Infinity 

但是乘法没有这种限制。

a = 10**1000000
...
a *= a
...
a *= a
...
a *= a
...
a.bit_length
 => 26575425
  

因此,如果您正在运行一个程序,该程序具有无限循环,并且计数器每秒增加数百或数千次,并且您必须以24 * 365的速度运行它,那可能会导致错误。

>

这是现实世界中对变为a pressing problem as 2038 approaches的32位整数而不是64位整数的关注。如果我们每秒增加一百万次计数器,则将花费近30万年的时间。我刚刚描述的是具有微秒分辨率的64位时间。

但是在Ruby中,您可以有效地制作一个所需的简单计数器。