我需要能够在Ruby中确定系统最大整数。有人知道怎么样,或者有可能吗?
答案 0 :(得分:79)
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))
答案 1 :(得分:45)
Ruby会在溢出时自动将整数转换为大整数类,因此(实际上)它们的大小没有限制。
如果您正在寻找机器的尺寸,即64位或32位,我找到了this trick at 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
),因为一位用于将其标记为整数而不是对象引用。
答案 2 :(得分:12)
阅读友好的手册?谁想要这样做?
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"
答案 3 :(得分:11)
在ruby中,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)
无耻地从ruby-talk discussion扯下来。看那里了解更多细节。
答案 4 :(得分:1)
自Ruby 2.4起没有最大值,因为Bignum和Fixnum统一为Integer。参见Feature #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
不会有任何溢出,会发生内存不足的情况。
答案 5 :(得分:0)
正如@JörgWMittag所指出的那样:在jruby中,修复num size总是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