近岡です。 In: [ruby-math:00959] Re: New methods of Integer >>|あと、やっぱり ilog2 の方が好きなんだよなあ。^^; >>それで同意が得られるのなら、私もその方がいいです。 >>私自身は ilog2 も必要なので定義して使っています。 > >bitlength をアルゴリズムでもどうしても ilog2 相当を求めてから >+1 をするような形になってしまうし。スクリプト中の使用頻度でも >ilog2 の方が多いような気がします。 > >ilog2 か bitlength、他の方はどうでしょうか? 私は、bitlength の方に1票を入れます。 使い勝手から言えば ilog2 の方に軍配が上がると思いますが、 名前の判りやすさの方を重視したいです。 Integer(log_2(i)) に相当するモノが欲しい人には、 i.ilog2 というメゾット名が、すぐ思いつくでしょう。 しかし、逆に、プログラム中の i.ilog2 を見て、 Integer(log_2(i)) ことだとすぐ判る人は少ないのではないでしょうか。 i.bitlength なら、詳細はわからなくても大体の所は判ると思います。 コンピュータサイエンス関係でもknuth教徒でもない人で、 文中に突然出てきた記号 lg が log2 のことだとすぐ判る人は、 少ないと思います。中には、lg が十進常用対数 log10 のことだと 判断する人もいるかもしれません。 なるべく一般的な名前にした方がよいと思います。 ==== ==== おまけ ==== ==== 再帰呼び出しを繰り返さない isqrt です。 # 私は、一体いつまで、このプログラムをいじっているのでしょうかね? Bitnum と Fixnum に分けるバージョンも作りましたが、 ここには分けないものを載せました。 3ビット以下の小さい非負整数(0〜7)に対しては、 配列を使って値を返していますが、 もちろん、サブルーチン化しても構いません。 変数 j の値は [ruby-math:00954]のisqrtのそれと同じになります。 # つまり、j = bitlength >> 2; とするものです。 ([ruby-math:00954]のisqrt_ini の bitlength) == (isqrtFのbitlength)−(l−k) == K+2 または K+3 class Integer FMAX = (1 << 3) - 1 ISQRT_TBL=[0,1,1,1, 2,2,2,2] # ←C言語では8バイトの配列 # ISQRT_TBL.siz > FMAX def isqrtF # bignum x; # long l,k,kk; short i,j; raise "argument is negative" if self < 0 return ISQRT_TBL[self] if self <= FMAX l = (bitlength - 2) & ~1; i = l.bitlength - 1; # if (1<<1)-2+2+1 <= FMAX.bitlength # i = l.bitlength - 2; # if (1<<2)-2+2+1 <= FMAX.bitlength # i = l.bitlength - 3; # if (1<<3)-2+2+1 <= FMAX.bitlength # i = l.bitlength - 4; # if (1<<4)-2+2+1 <= FMAX.bitlength k = (l >> i) & ~1; # k + 2 + 1 <= FMAX.bitlength x = ISQRT_TBL[ (self >> (l - k)) ] while (i = i - 1) >= 0 kk = k k = (l >> i) & ~1 j = (k - kk) >> 1 x = ((self >> (l - k + j)).div(x) + (x << j)) >> 1 end x -= 1 if x * x > self x end end 0----+----1----+----2----+----3----+----4----+----5----+----6 近岡 宣吉 Chikaoka, Nobuyoshi 富山県立高岡西高等学校(数楽科) E-mail : chikaoka-nobuyoshi / tym.ed.jp