我一直想知道Integer到达Float :: INFINITY之前的最大长度是多少。
> 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+开始,问题是整数可以有多大?
答案 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 Library的arbitrary 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中,您可以有效地制作一个所需的简单计数器。