mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* numeric.c (rb_num2ulong_internal): New function similart to
rb_num2ulong but integer wrap around flag is also returned. (rb_num2ulong): Use rb_num2ulong_internal. (rb_num2uint): Use rb_num2ulong_internal and the wrap around flag is used instead of negative_int_p(val). (rb_num2ushort): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40017 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
18affefbe5
commit
59182ccf69
3 changed files with 52 additions and 11 deletions
|
@ -1,3 +1,12 @@
|
|||
Sun Mar 31 13:47:04 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* numeric.c (rb_num2ulong_internal): New function similart to
|
||||
rb_num2ulong but integer wrap around flag is also returned.
|
||||
(rb_num2ulong): Use rb_num2ulong_internal.
|
||||
(rb_num2uint): Use rb_num2ulong_internal and the wrap around flag is
|
||||
used instead of negative_int_p(val).
|
||||
(rb_num2ushort): ditto.
|
||||
|
||||
Sun Mar 31 06:27:17 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* class.c (HAVE_METACLASS_P): should check FL_SINGLTON flag before get
|
||||
|
|
43
numeric.c
43
numeric.c
|
@ -1979,21 +1979,29 @@ rb_num2long(VALUE val)
|
|||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_num2ulong(VALUE val)
|
||||
static unsigned long
|
||||
rb_num2ulong_internal(VALUE val, int *wrap_p)
|
||||
{
|
||||
again:
|
||||
if (NIL_P(val)) {
|
||||
rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
|
||||
}
|
||||
|
||||
if (FIXNUM_P(val)) return FIX2LONG(val); /* this is FIX2LONG, inteneded */
|
||||
if (FIXNUM_P(val)) {
|
||||
long l = FIX2LONG(val); /* this is FIX2LONG, inteneded */
|
||||
if (wrap_p)
|
||||
*wrap_p = l < 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
switch (TYPE(val)) {
|
||||
case T_FLOAT:
|
||||
if (RFLOAT_VALUE(val) < ULONG_MAX_PLUS_ONE
|
||||
&& LONG_MIN_MINUS_ONE_IS_LESS_THAN(RFLOAT_VALUE(val))) {
|
||||
return (VALUE)RFLOAT_VALUE(val);
|
||||
double d = RFLOAT_VALUE(val);
|
||||
if (wrap_p)
|
||||
*wrap_p = d <= -1.0; /* NUM2ULONG(v) uses v.to_int conceptually. */
|
||||
return (unsigned long)d;
|
||||
}
|
||||
else {
|
||||
char buf[24];
|
||||
|
@ -2005,7 +2013,12 @@ rb_num2ulong(VALUE val)
|
|||
}
|
||||
|
||||
case T_BIGNUM:
|
||||
return rb_big2ulong(val);
|
||||
{
|
||||
unsigned long ul = rb_big2ulong(val);
|
||||
if (wrap_p)
|
||||
*wrap_p = RBIGNUM_NEGATIVE_P(val);
|
||||
return ul;
|
||||
}
|
||||
|
||||
default:
|
||||
val = rb_to_int(val);
|
||||
|
@ -2013,6 +2026,12 @@ rb_num2ulong(VALUE val)
|
|||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_num2ulong(VALUE val)
|
||||
{
|
||||
return rb_num2ulong_internal(val, NULL);
|
||||
}
|
||||
|
||||
#if SIZEOF_INT < SIZEOF_VALUE
|
||||
void
|
||||
rb_out_of_int(SIGNED_VALUE num)
|
||||
|
@ -2068,10 +2087,11 @@ rb_fix2int(VALUE val)
|
|||
unsigned long
|
||||
rb_num2uint(VALUE val)
|
||||
{
|
||||
VALUE num = rb_num2ulong(val);
|
||||
int wrap;
|
||||
unsigned long num = rb_num2ulong_internal(val, &wrap);
|
||||
|
||||
check_uint(num, negative_int_p(val));
|
||||
return (unsigned long)num;
|
||||
check_uint(num, wrap);
|
||||
return num;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
|
@ -2155,10 +2175,11 @@ rb_fix2short(VALUE val)
|
|||
unsigned short
|
||||
rb_num2ushort(VALUE val)
|
||||
{
|
||||
VALUE num = rb_num2ulong(val);
|
||||
int wrap;
|
||||
unsigned long num = rb_num2ulong_internal(val, &wrap);
|
||||
|
||||
check_ushort(num, negative_int_p(val));
|
||||
return (unsigned long)num;
|
||||
check_ushort(num, wrap);
|
||||
return num;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
|
|
|
@ -48,6 +48,17 @@ class TestNum2int < Test::Unit::TestCase
|
|||
if num.to_f.to_i == num
|
||||
assert_num2i_success_internal(result.to_s, func, num.to_f)
|
||||
end
|
||||
if num == result
|
||||
# The conversion functions such as NUM2INT uses to_int (conceptually).
|
||||
arg = num.to_f + 0.5
|
||||
if arg != num.to_f && arg.to_int == num
|
||||
assert_num2i_success_internal(result.to_s, func, arg)
|
||||
end
|
||||
arg = num.to_f - 0.5
|
||||
if arg != num.to_f && arg.to_int == num
|
||||
assert_num2i_success_internal(result.to_s, func, arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_num2i_error_internal(func, arg)
|
||||
|
|
Loading…
Reference in a new issue