Ruby最大整数


87

我需要能够确定Ruby中的系统最大整数。有人知道如何,或者是否可能?

Answers:


49

Ruby在溢出时会自动将整数转换为大整数类,因此(实际上)对整数的大小没有限制。

如果您正在寻找机器的大小,即64位或32位,我在ruby-forum.com上找到了这个技巧

machine_bytes = ['foo'].pack('p').size
machine_bits = machine_bytes * 8
machine_max_signed = 2**(machine_bits-1) - 1
machine_max_unsigned = 2**machine_bits - 1

如果要查找Fixnum对象的大小(足够小以在单个机器字中存储的整数),则可以调用0.size以获取字节数。我猜它在32位版本上应该是4,但是我现在无法测试。另外,最大的Fixnum显然是2**30 - 1(或2**62 - 1),因为使用一位将其标记为整数而不是对象引用。


1
很确定您要2 **(machine_size * 8)-1; 2 ** 4-1 = 15这不是很大的东西。
Cebjyre 2009年

哎呀,我想我开始考虑字节而不是位。
马修·克鲁姆利

10
警告:该代码是无用的。阅读编辑内容,忽略代码。它找不到Ruby的最大容量。它为不使用标记指针的代码找到它。
CJ。

现在(2018-01-21)即使在Windows上的64bit红宝石中,它也是
32bits

81
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))

5
为什么为符号减去2位而不是1位?我对此进行了测试,这似乎是正确的,但是Ruby为什么使用2位作为符号?
马赛厄斯'02

29
@Matthias一个额外的位用于将值标记为整数(与指向对象的指针相反)。
马修·克鲁姆利

2
至少对于JRuby并非如此。在JRuby中,Fixnum无论机器字长如何,始终为64位(而不是YARV中的63或31位),并且没有标签位。
约尔格W¯¯米塔格

13

阅读友好手册?谁想这样做?

start = Time.now
largest_known_fixnum = 1
smallest_known_bignum = nil

until smallest_known_bignum == largest_known_fixnum + 1
  if smallest_known_bignum.nil?
    next_number_to_try = largest_known_fixnum * 1000
  else
    next_number_to_try = (smallest_known_bignum + largest_known_fixnum) / 2 # Geometric mean would be more efficient, but more risky
  end

  if next_number_to_try <= largest_known_fixnum ||
       smallest_known_bignum && next_number_to_try >= smallest_known_bignum
    raise "Can't happen case" 
  end

  case next_number_to_try
    when Bignum then smallest_known_bignum = next_number_to_try
    when Fixnum then largest_known_fixnum = next_number_to_try
    else raise "Can't happen case"
  end
end

finish = Time.now
puts "The largest fixnum is #{largest_known_fixnum}"
puts "The smallest bignum is #{smallest_known_bignum}"
puts "Calculation took #{finish - start} seconds"

这似乎是从Fixnum到Bignum转换时返回数字的唯一答案,对我而言,这意味着这是Ruby中最大的Fixnum。
Tin Man

11

在红宝石中,Fixnums会自动转换为Bignums。

要找到可能的最高Fixnum,可以执行以下操作:

class Fixnum
 N_BYTES = [42].pack('i').size
 N_BITS = N_BYTES * 8
 MAX = 2 ** (N_BITS - 2) - 1
 MIN = -MAX - 1
end
p(Fixnum::MAX)

一场红宝石讨论无耻地撕掉了。在此处查看更多详细信息。


5
如果执行puts (Fixnum::MAX + 1).class此操作,则不会Bignum像看起来的那样返回。如果更改816它将。
Tin Man'1

现在不可用
allenhwkim 2013年

1

自Ruby 2.4以来,没有最大限制,因为Bignum和Fixnum统一为Integer。请参阅功能12005

> (2 << 1000).is_a? Fixnum
(irb):322: warning: constant ::Fixnum is deprecated
=> true

> 1.is_a? Bignum
(irb):314: warning: constant ::Bignum is deprecated
=> true

> (2 << 1000).class
=> Integer

不会有任何溢出,将会发生内存不足的情况。


0

正如@JörgW Mittag指出的那样:在jruby中,固定数字大小始终为8个字节。此代码段显示了事实:

fmax = ->{
  if RUBY_PLATFORM == 'java'
    2**63 - 1
  else
    2**(0.size * 8 - 2) - 1
  end
}.call

p fmax.class     # Fixnum

fmax = fmax + 1  

p fmax.class     #Bignum
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.