From: matz@... (Yukihiro Matsumoto) Date: 1998-07-09T16:36:31+09:00 Subject: [ruby-list:8660] Re: can't build 1.1b9_28 on digital-unix まつもと ゆきひろです In message "[ruby-list:8654] Re: can't build 1.1b9_28 on digital-unix" on 98/07/09, Go Nakagawa writes: |中川です。 |> できれば,以下の結果をそれぞれ教えて下さい. |> |> % ruby -e 'p 1<<1014' |> % ruby -e 'p 2**1014' | |直接の回答にはなりませんが、いままで調べた結果を報告します。 こちらも教えて下さいね. |o その1 -- FIXNUM_{MAX|MIN} がおかしい? |#define LONG_MAX 9223372036854775807 |が定義されているので、以下のパッチをあてたらそれっぽく動くように |なりました。FIXNUM_MIN の処理は自信ないです。その場しのぎなので |そういう目でみてください :-) これだとFIXNUMはintのサイズ(4バイト)になります.個人的には 64 bitマシンではFIXNUMは8バイトの方が良いと思っているので, 以下のパッチの方を推奨します. --- numeric.c 1998/07/03 07:06:32 1.1.1.2.2.23 +++ numeric.c 1998/07/09 07:15:09 @@ -791,3 +791,3 @@ - sprintf(buf, fmt, FIX2INT(x)); + sprintf(buf, fmt, FIX2LONG(x)); return str_new2(buf); 多分,sprintfにもパッチを当てる必要があるでしょう. --- sprintf.c 1998/07/03 07:06:36 1.1.1.2.2.7 +++ sprintf.c 1998/07/09 07:25:03 @@ -352,3 +352,3 @@ } - sprintf(fbuf, "%%%c", *p); + sprintf(fbuf, "%l%%c", *p); sprintf(s, fbuf, v); @@ -471,2 +471,3 @@ if (c == 'D') c = 'd'; + if (c == 'O') c = 'o'; int_retry: @@ -544,3 +545,3 @@ else { - int max = 11; + int max = 12; @@ -613,2 +614,5 @@ *buf++ = '%'; + if (strchr("doOXx", c)) { + *buf++ = 'l'; + } if (flags & FSHARP) *buf++ = '#'; |o その2 -- lshift がおかしい? | |FIXNUM_MIN の処理が自信ないので確認しようとしました。 |んー、なんか変。 |どうやら 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); | } | |がうまくいってないみたいです。 こんな感じでしょうか. --- numeric.c 1998/07/03 07:06:32 1.1.1.2.2.23 +++ numeric.c 1998/07/09 07:31:25 @@ -1101,3 +1101,3 @@ if (width > (sizeof(VALUE)*CHAR_BIT-1) - || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) { + || (unsigned long)val>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) { return big_lshift(int2big(val), y); |o その3 -- pow がおかしい? |んー、やっぱり変。 これはいかが? --- bignum.c 1998/06/19 09:31:58 1.1.1.2.2.18 +++ bignum.c 1998/07/08 09:19:06 @@ -587,3 +587,3 @@ for (i = 0, num = 0; i < len; i++) { - num += (long)(BDIGITS(x)[i] + BDIGITS(y)[i]); + num += BDIGITS(x)[i] + BDIGITS(y)[i]; BDIGITS(z)[i] = BIGLO(num); @@ -612,3 +612,3 @@ case T_FIXNUM: - y = int2big(FIX2INT(y)); + y = int2big(FIX2LONG(y)); /* fall through */ @@ -631,3 +631,3 @@ case T_FIXNUM: - y = int2big(FIX2INT(y)); + y = int2big(FIX2LONG(y)); /* fall through */ @@ -653,6 +653,6 @@ - if (FIXNUM_P(x)) x = int2big(FIX2INT(x)); + if (FIXNUM_P(x)) x = int2big(FIX2LONG(x)); switch (TYPE(y)) { case T_FIXNUM: @@ -919,3 +919,3 @@ double d; - VALUE z; + long yy; @@ -928,3 +928,3 @@ case T_BIGNUM: - if (RBIGNUM(y)->sign) goto pos_big; + Warn("in a**b, b may be too big"); d = big2dbl(y); @@ -933,18 +933,12 @@ case T_FIXNUM: - if (FIX2INT(y) > 0) goto pos_big; - d = (double)FIX2INT(y); - break; - - default: - return num_coerce_bin(x, y); - } - return float_new(pow(big2dbl(x), d)); + yy = NUM2LONG(y); + if (yy > 0) { + VALUE z; - pos_big: z = x; for (;;) { - y = rb_funcall(y, '-', 1, INT2FIX(1)); - if (y == INT2FIX(0)) break; - while (rb_funcall(y, '%', 1, INT2FIX(2)) == INT2FIX(0)) { - y = rb_funcall(y, '/', 1, INT2FIX(2)); + yy = yy - 1; + if (yy == 0) break; + while (yy % 2 == 0) { + yy = yy / 2; x = big_mul(x, x); @@ -955,2 +949,10 @@ } + d = (double)yy; + break; + + default: + return num_coerce_bin(x, y); + } + return float_new(pow(big2dbl(x), d)); +}