In article <200304280150.h3S1onW4014870 / sharui.nakada.kanuma.tochigi.jp>, nobu.nakada / nifty.ne.jp writes: > れも自前でBigintを実装しているし、Bignum#to_fにも誤差があること > を考えると、まずそっちを直したほうがいいのではないかという気が > して来ました。 Bignum#to_f がうまくいかない場合があるということ自体に反論するわけでは ないんですが、 In article <200304230733.h3N7X5pj026792 / sharui.nakada.kanuma.tochigi.jp>, nobu.nakada / nifty.ne.jp writes: > Bignum#to_fも誤差を含んでるようです。 > $ ruby -e 'p 39560152763386141.to_f' > 3.9560152763386144e+16 この例はちと違うんじゃないかと思います。 39560152763386141 は 0b10001100100010111011111111010100101110001100100100011101 なので 56bit あるわけですが、IEEE754 の倍精度は仮数部 53bit なので下位 3bit の 0b101 を丸める必要があって、これは 0b1000 の半分よりも大きいの で繰り上がりになり、 0b10001100100010111011111111010100101110001100100100100 * 2**3 となって、これは to_f で求まった 3.9560152763386144e+16 つまり 0b1.0001100100010111011111111010100101110001100100100100 * 2**55 そのものなのではなかろうか、ということですが。 Bignum#to_f は基数の変換をするわけではないので、危ないのは複数回の丸め が起きる場合ですかね。つまり、BITSPERDIG の倍数の中で 53bit 以上のもの のうち最小のもの (というのは、とある環境では 64bit) 以下では面白いこと は起きないんじゃないかと思います。 -- [田中 哲][たなか あきら][Tanaka Akira]