summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-07-16 10:39:42 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-07-16 10:39:42 +0000
commit04f09ef8a19663ec42158fda1c1b8332a8f0ce42 (patch)
treeb9fbf2702a405b2db2925d7609d65397b69ec6d2 /bignum.c
parent858a832d40845a951e2cf01c0482e7d7014a8c81 (diff)
* bignum.c (rb_integer_float_eq): new function.
(rb_big_eq): use rb_integer_float_eq. * internal.h (rb_integer_float_eq): declared. * numeric.c (flo_eq): use rb_integer_float_eq. (fix_equal): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/bignum.c b/bignum.c
index 45c1784c53..1e8baee8dd 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1481,6 +1481,38 @@ rb_integer_float_cmp(VALUE x, VALUE y)
return INT2FIX(-1);
}
+VALUE
+rb_integer_float_eq(VALUE x, VALUE y)
+{
+ double yd = RFLOAT_VALUE(y);
+ double yi, yf;
+
+ if (isnan(yd) || isinf(yd))
+ return Qfalse;
+ yf = modf(yd, &yi);
+ if (yf != 0)
+ return Qfalse;
+ if (FIXNUM_P(x)) {
+#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
+ double xd = (double)FIX2LONG(x);
+ if (xd != yd)
+ return Qfalse;
+ return Qtrue;
+#else
+ long xl, yl;
+ if (yi < LONG_MIN || LONG_MAX < yi)
+ return Qfalse;
+ xl = FIX2LONG(x);
+ yl = (long)yi;
+ if (xl != yl)
+ return Qfalse;
+ return Qtrue;
+#endif
+ }
+ y = rb_dbl2big(yi);
+ return rb_big_eq(x, y);
+}
+
/*
* call-seq:
* big <=> numeric -> -1, 0, +1 or nil
@@ -1654,7 +1686,7 @@ rb_big_eq(VALUE x, VALUE y)
case T_BIGNUM:
break;
case T_FLOAT:
- return rb_integer_float_cmp(x, y) == INT2FIX(0) ? Qtrue : Qfalse;
+ return rb_integer_float_eq(x, y);
default:
return rb_equal(y, x);
}