From: Yusuke ENDOH Date: 2007-07-17T22:30:38+09:00 Subject: [ruby-dev:31242] p(65536**(1<<29)) stalls 遠藤と申します。 以下のようにすると反応がなくなります。Ctrl+C でも止められません。 $ ./ruby -ve 'p(65536**(1<<29))' ruby 1.8.6 (2007-07-17 patchlevel 5000) [i686-linux] $ ./ruby -ve 'p(65536**(1<<29))' ruby 1.9.0 (2007-07-17 patchlevel 0) [i686-linux] bignum の大きさのチェックで integer overflow しているのが原因のようです。 1.8 での応急措置です。 Index: bignum.c =================================================================== --- bignum.c (revision 12809) +++ bignum.c (working copy) @@ -1755,8 +1755,13 @@ if (yy > 0) { VALUE z = 0; long mask; + VALUE f = 1, t1 = RBIGNUM(x)->len * SIZEOF_BDIGITS; + if (t1 / SIZEOF_BDIGITS == RBIGNUM(x)->len && t1 % SIZEOF_BDIGITS == 0) { + VALUE t2 = t1 * yy; + if (t2 / yy == t1 && t2 % yy == 0 && t2 <= 1024*1024) f = 0; + } - if (RBIGNUM(x)->len * SIZEOF_BDIGITS * yy > 1024*1024) { + if (f) { rb_warn("in a**b, b may be too big"); d = (double)yy; break; 1024*1024 が即値で埋め込まれているのが気持ち悪いんですが、 bignum の最大値ってちゃんと決まってないんでしょうか。 ついでに、重箱の隅ですが、以下の仕様変更は意図されたものでしょうか。 $ ./ruby -ve 'p(0**(1<<30))' ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux] -e:1: warning: in a**b, b may be too big 0.0 $ ./ruby -ve 'p(0**(1<<30))' ruby 1.8.6 (2007-07-17 patchlevel 5000) [i686-linux] 0 -- Yusuke ENDOH