simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

RubyのFixnumの最大値と最小値

気になったので調べてみました。
Rubyではある値を越えた時にFixnumからBignumへと変わります。

p (2**0).class #=> 1
p (2**10).class #=> 1024
p (2**100).class #=> 1267650600228229401496703205376
p (2**1000).class #=> 略
Fixnum
Fixnum
Bignum
Bignum

そこで二分探索を行ってFixnumとBignumの境界値を調べてみました。

class Fixnum
  class << self
    def const_missing(name)
      if [:MAX,:MIN].include?(name)
        generate_max_min
        self.const_get(name)
      else
        super
      end
    end

    def generate_max_min
      a = 0
      b = 2**256

      while b-a > 1
        c = (a+b)/2

        if c.instance_of?(Fixnum)
          a = c
        else
          b = c
        end
      end

      self.const_set(:MAX, a)
      self.const_set(:MIN, -(a+1))
    end
  end
end

p Fixnum::MAX
p Fixnum::MIN
4611686018427387903
-4611686018427387904

ちゃんと境界値が取得できているかチェックします

p 4611686018427387903.class
p 4611686018427387904.class
p -4611686018427387904.class
p -4611686018427387905.class
Fixnum
Bignum
Fixnum
Bignum

ちゃんと取得できていました。試していないですが、実行する環境によって値が変わったりするかも。

追記

実装レベルで説明があってとても参考になりました
http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum