Numeric にある floor、ceil、truncate、round は、あまり意味がないばかり
でなく、有害だと思うので削除していいと思っていますが、ちょっと別な定義
を考えてみました。

ruby でつかわれる Complex を除く数、Fixnum、Bignum、Float、Rational、
BigDecimal は、それが表している数が正しいとして、正確に Rational に変
換可能なはずです。

より一般的な有理数とすることで一般化することができます。一方、現在の実
装は、浮動小数点数に還元してしまいますが、これはあきらかに問題があると
思います。

あるいは、Rational の存在 (= to_r の存在) を前提にせずに、それぞれのク
ラスで、numerator と denominator を定義することにします。Rational が存
在しない場合もあるし、逆に mathn 環境では、Integer から Rational に変
換したりする意味がない、ということもあります。

現実的には、あまり意味がないかもしれないけど、このようにすることも可能
ではないかと思いました。


require 'rational'
require 'complex'
require 'bigdecimal'

class Numeric

  def numerator() to_r.numerator end
  def denominator() to_r.denominator end

  def floor
    numerator.div(denominator)
  end

  def ceil
    -((-numerator).div(denominator))
  end

  def truncate
    if numerator < 0
      return -((-numerator).div(denominator))
    end
    numerator.div(denominator)
  end

  alias_method :to_i, :truncate

  def round
    if numerator < 0
      num = -numerator
      num = num * 2 + denominator
      den = denominator * 2
      -(num.div(den))
    else
      num = numerator * 2 + denominator
      den = denominator * 2
      num.div(den)
    end
  end

end

class Float

  def decode
    f, n = Math.frexp(self)
    f = Math.ldexp(f, Float::MANT_DIG).to_i
    n -= Float::MANT_DIG
    return f, n
  end

  private :decode

  def to_r
    f, n = decode
    f * Float::RADIX ** n
  end

end

class BigDecimal

  def to_r
    s, f, b, e = split
    Rational(s * f.to_i * b ** (e - f.size))
  end

end

class Complex

  undef numerator
  undef denominator
  undef floor
  undef ceil
  undef truncate
  undef round

end