aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-27 00:42:11 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-27 00:42:11 +0000
commita18f3f4dbdec695765637b21b9c2526f30e6946c (patch)
tree111fd30fd67a4d049baba70a3a36b470a7de8366
parent70f820784179fa6d84220b335b3a286ced0eb8fd (diff)
downloadruby-a18f3f4dbdec695765637b21b9c2526f30e6946c.tar.gz
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
-rw-r--r--ChangeLog6
-rw-r--r--object.c29
-rw-r--r--test/ruby/test_integer.rb10
3 files changed, 26 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index c03b6adcf6..40038fcb05 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
string.
diff --git a/object.c b/object.c
index 228b67e8f8..05bef4df28 100644
--- a/object.c
+++ b/object.c
@@ -2684,30 +2684,23 @@ rb_convert_to_integer(VALUE val, int base)
{
VALUE tmp;
- switch (TYPE(val)) {
- case T_FLOAT:
+ if (RB_FLOAT_TYPE_P(val)) {
+ double f;
if (base != 0) goto arg_error;
- if (RFLOAT_VALUE(val) <= (double)FIXNUM_MAX
- && RFLOAT_VALUE(val) >= (double)FIXNUM_MIN) {
- break;
- }
- return rb_dbl2big(RFLOAT_VALUE(val));
-
- case T_FIXNUM:
- case T_BIGNUM:
+ f = RFLOAT_VALUE(val);
+ if (FIXABLE(f)) return LONG2FIX((long)f);
+ return rb_dbl2big(f);
+ }
+ else if (RB_INTEGER_TYPE_P(val)) {
if (base != 0) goto arg_error;
return val;
-
- case T_STRING:
+ }
+ else if (RB_TYPE_P(val, T_STRING)) {
return rb_str_to_inum(val, base, TRUE);
-
- case T_NIL:
+ }
+ else if (NIL_P(val)) {
if (base != 0) goto arg_error;
rb_raise(rb_eTypeError, "can't convert nil into Integer");
- break;
-
- default:
- break;
}
if (base != 0) {
tmp = rb_check_string_type(val);
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index 32c3511576..00c3c12577 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -104,6 +104,16 @@ class TestInteger < Test::Unit::TestCase
obj = Struct.new(:s).new(%w[42 not-an-integer])
def obj.to_str; s.shift; end
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
def test_int_p