中川です。 From: matz / netlab.co.jp (Yukihiro Matsumoto) Subject: [ruby-list:8647] Re: can't build 1.1b9_28 on digital-unix Date: Wed, 8 Jul 1998 17:38:41 +0900 > まつもと ゆきひろです > できれば,以下の結果をそれぞれ教えて下さい. > > % ruby -e 'p 1<<1014' > % ruby -e 'p 2**1014' 直接の回答にはなりませんが、いままで調べた結果を報告します。 o その1 -- FIXNUM_{MAX|MIN} がおかしい? for i in 0..100 print ("i=", i, " ", (1<<i).type, " ", (1<<i),"\n") end を実行すると (一部略) i=26 Fixnum 67108864 i=27 Fixnum 134217728 i=28 Fixnum 268435456 i=29 Fixnum 536870912 i=30 Fixnum 1073741824 i=31 Fixnum foo.rb:2:in `to_s': integer -2147483648 too big to convert to `int'. (ArgumentError) from foo.rb:2:in `print' from foo.rb:2 from foo.rb:1:in `each' from foo.rb:1 で終了します。/usr/include/limits.h で #define LONG_MAX 9223372036854775807 が定義されているので、以下のパッチをあてたらそれっぽく動くように なりました。FIXNUM_MIN の処理は自信ないです。その場しのぎなので そういう目でみてください :-) -------- ここから *** ruby-1.1b9_29/ruby.h Fri Jun 26 18:44:36 1998 --- ruby-1.1b9_29-alpha/ruby.h Wed Jul 08 17:59:50 1998 *************** *** 112,119 **** --- 112,124 ---- # endif #endif + #if (SIZEOF_LONG == 8) && (SIZEOF_INT == 4) + #define FIXNUM_MAX (INT_MAX>>1) + #define FIXNUM_MIN RSHIFT((int)INT_MIN,1) + #else #define FIXNUM_MAX (LONG_MAX>>1) #define FIXNUM_MIN RSHIFT((long)LONG_MIN,1) + #endif #define FIXNUM_FLAG 0x01 #define INT2FIX(i) (VALUE)(((long)(i))<<1 | FIXNUM_FLAG) -------- ここまで o その2 -- lshift がおかしい? FIXNUM_MIN の処理が自信ないので確認しようとしました。 for i in 0..100 print ("i=", i, " ", (-1<<i).type, " ", (-1<<i),"\n") end の結果はこんな感じです。 (一部略) i=28 Fixnum -268435456 i=29 Fixnum -536870912 i=30 Fixnum -1073741824 i=31 Bignum -2147483648 i=32 Fixnum 0 i=33 Fixnum 0 i=34 Fixnum 0 (中略 0が続く) i=60 Fixnum 0 i=61 Fixnum 0 i=62 Bignum -4611686018427387904 i=63 Bignum -9223372036854775808 (後略) んー、なんか変。 どうやら sizeof(VALUE)==sizeof(unsigned long) なので numeric.c の fix_lshift() のうち、 if (width > (sizeof(VALUE)*CHAR_BIT-1) || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) { return big_lshift(int2big(val), y); } がうまくいってないみたいです。 パッチありません。面目ないっす。 -1<<30 == -1073741824 が Fixnum というのは x86 な環境と結果が 違うのですが追いきれてません。 o その3 -- pow がおかしい? for i in 0..100 print ("i=", i, " ", (2**i).type, " ", (2**i),"\n") end の結果はこうなりました。 (一部略) i=28 Fixnum 268435456 i=29 Fixnum 536870912 i=30 Bignum 1073741824 i=31 Bignum 2147483648 i=32 Fixnum 0 i=33 Fixnum 0 i=34 Fixnum 0 (以下おなじ) んー、やっぱり変。 原因は追いきれてません。面目ないっす。 -- 中川 剛 / nakagawa / shizuokanet.ne.jp