object.c: fixable float to fixnum

* object.c (rb_convert_to_integer): convert a fixable float to a
  fixnum directly without the convesion method, as well as bignum
  case.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56497 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2016-10-27 00:42:11 +00:00
parent cc08515cf8
commit c94855855e
3 changed files with 26 additions and 19 deletions

View File

@ -1,4 +1,8 @@
Thu Oct 27 09:12:32 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> Thu Oct 27 09:42:09 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* object.c (rb_convert_to_integer): convert a fixable float to a
fixnum directly without the convesion method, as well as bignum
case.
* object.c (rb_convert_to_integer): should not drop the converted * object.c (rb_convert_to_integer): should not drop the converted
string. string.

View File

@ -2684,30 +2684,23 @@ rb_convert_to_integer(VALUE val, int base)
{ {
VALUE tmp; VALUE tmp;
switch (TYPE(val)) { if (RB_FLOAT_TYPE_P(val)) {
case T_FLOAT: double f;
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
if (RFLOAT_VALUE(val) <= (double)FIXNUM_MAX f = RFLOAT_VALUE(val);
&& RFLOAT_VALUE(val) >= (double)FIXNUM_MIN) { if (FIXABLE(f)) return LONG2FIX((long)f);
break; return rb_dbl2big(f);
} }
return rb_dbl2big(RFLOAT_VALUE(val)); else if (RB_INTEGER_TYPE_P(val)) {
case T_FIXNUM:
case T_BIGNUM:
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
return val; return val;
}
case T_STRING: else if (RB_TYPE_P(val, T_STRING)) {
return rb_str_to_inum(val, base, TRUE); return rb_str_to_inum(val, base, TRUE);
}
case T_NIL: else if (NIL_P(val)) {
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
rb_raise(rb_eTypeError, "can't convert nil into Integer"); rb_raise(rb_eTypeError, "can't convert nil into Integer");
break;
default:
break;
} }
if (base != 0) { if (base != 0) {
tmp = rb_check_string_type(val); tmp = rb_check_string_type(val);

View File

@ -104,6 +104,16 @@ class TestInteger < Test::Unit::TestCase
obj = Struct.new(:s).new(%w[42 not-an-integer]) obj = Struct.new(:s).new(%w[42 not-an-integer])
def obj.to_str; s.shift; end def obj.to_str; s.shift; end
assert_equal(42, Integer(obj, 10)) assert_equal(42, Integer(obj, 10))
assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
begin;
class Float
undef to_int
def to_int; raise "conversion failed"; end
end
assert_equal (1 << 100), Integer((1 << 100).to_f)
assert_equal 1, Integer(1.0)
end;
end end
def test_int_p def test_int_p