正木です。 In [ruby-math:00940] |これはオリジナルの [ruby-math:00933] を少し変形していますよね。 |多分オリジナルのままの方がちょっと速いと思います。つまり、 オリジナルでは bignum が対象だったので必要なかったのですが、 Ruby script に書き直すときに return 2 if self < 9 return 3 if self < 16 を書くのがいやで書き換えてしまいました。これがそんなに速度に 影響するとは思いませんでした。 |で、さらにたった今投げられた、近岡さんの [ruby-math:00939] を見たら | | x = x << j | x = (x + self.div(x)) >> 1 | |は、 | | x = ((x << j) + (self >> j).div(x)) >> 1 | |としてますね。ううむ、なるほど!気がつかなかった。こちらの方が割 これは速度の向上にかなり効きそうです。 |また、 | | x = ((x << j) + (self >> j).div(x)) >> 1 | |という工夫も値が小さめになるので、isqrtC2 でさえちょっと不安です。 これは大丈夫だと思います。 調べてみると殆どの場合 isqrt2_ini の段階で正しい値が得られています。 Factorial[1000*n].isqrtC2 (n=10..20) で実際に loop が回るのは n=12 のときだけ。 (2**(2**n-1)-1).isqrtC2 (n=1..19) では n=5,6 のみ。 それにしてもアイデアを出しあうとどんどん早くなりますね。