From: "U.Nakamura" Date: 2008-07-03T21:34:31+09:00 Subject: [ruby-dev:35341] Re: NUM2xxx こんにちは、なかむら(う)です。 In message "[ruby-dev:33683] NUM2xxx" on Feb.10,2008 17:47:51, wrote: > ふと NUM2xxx が受け付ける値の範囲を調べたんですが、unsigned > なのが負の値を受け付けるのってそういうものなんでしたっけ? > > int = long = 32bit, long long = 64bit な環境 > NUM2INT: -0x80000000 .. 0x7fffffff > NUM2UINT: -0x7fffffff .. 0xffffffff > NUM2LONG: -0x80000000 .. 0x7fffffff > NUM2ULONG: -0x7fffffff .. 0xffffffff > NUM2LL -0x8000000000000000 .. 0x7fffffffffffffff > NUM2ULL -0xffffffffffffffff .. 0xffffffffffffffff > > int = 32bit, long = long long = 64bit (LP64) な環境 > NUM2INT: -0x80000000 .. 0x7fffffff > NUM2UINT: -0x7fffffffffffffff .. 0xffffffff > NUM2LONG: -0x8000000000000000 .. 0x7fffffffffffffff > NUM2ULONG: -0x7fffffffffffffff .. 0xffffffffffffffff > NUM2LL: -0x8000000000000000 .. 0x7fffffffffffffff > NUM2ULL: -0xffffffffffffffff .. 0xffffffffffffffff > > とくに、LP64 での NUM2UINT が -0x7fffffffffffffff まで受け付 > けるのはかなり変な気がします。 古い話ですが、IRCで指摘されたので考えてみました。 とりあえず、NUM2U*が負の値を受け付けるのはそういうものだと仮 定して、LP64のNUM2UINTだけ対策すると、こんなもんでしょうか? Index: numeric.c =================================================================== --- numeric.c (revision 17790) +++ numeric.c (working copy) @@ -1585,10 +1585,10 @@ check_int(SIGNED_VALUE num) } static void -check_uint(VALUE num) +check_uint(VALUE num, int sign) { if (num > UINT_MAX) { - rb_raise(rb_eRangeError, "integer %"PRIuVALUE " too big to convert to `unsigned int'", num); + rb_raise(rb_eRangeError, "integer %"PRIuVALUE " too %s to convert to `unsigned int'", sign ? "small" : "big", num); } } @@ -1615,9 +1615,7 @@ rb_num2uint(VALUE val) { unsigned long num = rb_num2ulong(val); - if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) { - check_uint(num); - } + check_uint(num, RTEST(val, '<', 1, rb_funcall(INT2FIX(0)))); return num; } それでは。 -- U.Nakamura