93

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

4

6 回答 6

81
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))
于 2009-04-10T00:12:25.657 回答
50

当整数溢出时,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),因为一位用于将其标记为整数而不是对象引用。

于 2009-02-11T07:23:15.290 回答
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"
于 2009-02-11T23:59:47.793 回答
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)

无耻地从红宝石谈话中扯下来。在那里查看更多详细信息。

于 2009-02-11T07:18:10.387 回答
3

自 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

不会有任何溢出,会发生内存不足。

于 2020-03-24T10:06:05.940 回答
0

正如@Jörg W Mittag 指出的那样:在 jruby 中,固定 num 大小始终为 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
于 2017-03-27T07:42:42.987 回答