aboutsummaryrefslogtreecommitdiffstats
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
parent858a832d40845a951e2cf01c0482e7d7014a8c81 (diff)
downloadruby-04f09ef8a19663ec42158fda1c1b8332a8f0ce42.tar.gz
* 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
-rw-r--r--ChangeLog10
-rw-r--r--bignum.c34
-rw-r--r--internal.h1
-rw-r--r--numeric.c4
4 files changed, 46 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 0edab34843..2ba68ea241 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Jul 16 19:24:01 2012 Tanaka Akira <akr@fsij.org>
+
+ * 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.
+
Mon Jul 16 19:02:31 2012 Tanaka Akira <akr@fsij.org>
* bignum.c (rb_integer_float_cmp): rename a local variable.
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);
}
diff --git a/internal.h b/internal.h
index 03fa38a8c4..a80ea30c9c 100644
--- a/internal.h
+++ b/internal.h
@@ -50,6 +50,7 @@ VALUE rb_ary_cat(VALUE, const VALUE *, long);
VALUE rb_big_fdiv(VALUE x, VALUE y);
VALUE rb_big_uminus(VALUE x);
VALUE rb_integer_float_cmp(VALUE x, VALUE y);
+VALUE rb_integer_float_eq(VALUE x, VALUE y);
/* class.c */
VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
diff --git a/numeric.c b/numeric.c
index 52a43547c8..b40f0695b8 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1055,7 +1055,7 @@ flo_eq(VALUE x, VALUE y)
switch (TYPE(y)) {
case T_FIXNUM:
case T_BIGNUM:
- return rb_integer_float_cmp(y, x) == INT2FIX(0) ? Qtrue : Qfalse;
+ return rb_integer_float_eq(y, x);
case T_FLOAT:
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
@@ -2947,7 +2947,7 @@ fix_equal(VALUE x, VALUE y)
case T_BIGNUM:
return rb_big_eq(y, x);
case T_FLOAT:
- return rb_integer_float_cmp(x, y) == INT2FIX(0) ? Qtrue : Qfalse;
+ return rb_integer_float_eq(x, y);
default:
return num_equal(x, y);
}