summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-12-19 09:20:20 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-12-19 09:20:20 +0000
commitbaa00aa2506745308a598ce91e65a727ba25f30f (patch)
treefc289dbd1d10586ba6537ab070a7f42bd7bc9cb6 /numeric.c
parenta0a14ed14a86b7204ba3e9d557a296ca08a8bb8d (diff)
* numeric.c (num_step): use DBL_EPSILON.
* array.c (rb_check_array_type): new function: return an array (convert if possible), or nil. * string.c (rb_check_string_type): new function: return a string (convert if possible), or nil. * numeric.c (rb_dbl_cmp): returns nil if values are not comparable. * numeric.c (fix_cmp,flo_cmp): use rb_num_coerce_cmp() * bignum.c (rb_big_cmp): ditto. * numeric.c (rb_num_coerce_cmp): new coercing function for "<=>", which does not raise TypeError. * numeric.c (do_coerce): can be supress exception now. * object.c (rb_mod_cmp): should return nil for non class/module objects. * re.c (rb_reg_eqq): return false if the argument is not a string. now returns boolean value. * class.c (rb_include_module): argument should be T_MODULE, not T_class, nor T_ICLASS. * eval.c (is_defined): "defined?" should return "assignment" for attribute assignment (e.g. a.foo=b) and indexed assignment (e.g. a[2] = 44). * parse.y (aryset): use NODE_ATTRASGN. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3169 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/numeric.c b/numeric.c
index c1e064588b..0da0e64279 100644
--- a/numeric.c
+++ b/numeric.c
@@ -13,10 +13,19 @@
#include "ruby.h"
#include <math.h>
#include <stdio.h>
+
#if defined(__FreeBSD__) && __FreeBSD__ < 4
#include <floatingpoint.h>
#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifndef DBL_EPSILON
+#define 2.2204460492503131E-16
+#endif
+
static ID id_coerce, id_to_i, id_div;
VALUE rb_cNumeric;
@@ -61,32 +70,46 @@ coerce_rescue(x)
return Qnil; /* dummy */
}
-static void
-do_coerce(x, y)
+static int
+do_coerce(x, y, err)
VALUE *x, *y;
+ int err;
{
VALUE ary;
VALUE a[2];
a[0] = *x; a[1] = *y;
- ary = rb_rescue(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a);
+ ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a);
if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
- rb_raise(rb_eTypeError, "coerce must return [x, y]");
+ if (err) {
+ rb_raise(rb_eTypeError, "coerce must return [x, y]");
+ }
+ return Qfalse;
}
*x = RARRAY(ary)->ptr[0];
*y = RARRAY(ary)->ptr[1];
+ return Qtrue;
}
VALUE
rb_num_coerce_bin(x, y)
VALUE x, y;
{
- do_coerce(&x, &y);
+ do_coerce(&x, &y, Qtrue);
return rb_funcall(x, rb_frame_last_func(), 1, y);
}
+VALUE
+rb_num_coerce_cmp(x, y)
+ VALUE x, y;
+{
+ if (do_coerce(&x, &y, Qfalse))
+ return rb_funcall(x, rb_frame_last_func(), 1, y);
+ return Qnil;
+}
+
static VALUE
num_copy_object(x, y)
VALUE x, y;
@@ -110,7 +133,7 @@ num_uminus(num)
VALUE zero;
zero = INT2FIX(0);
- do_coerce(&zero, &num);
+ do_coerce(&zero, &num, Qtrue);
return rb_funcall(zero, '-', 1, num);
}
@@ -494,7 +517,7 @@ rb_dbl_cmp(a, b)
if (a == b) return INT2FIX(0);
if (a > b) return INT2FIX(1);
if (a < b) return INT2FIX(-1);
- rb_raise(rb_eFloatDomainError, "comparing NaN");
+ return Qnil;
}
static VALUE
@@ -518,7 +541,7 @@ flo_cmp(x, y)
break;
default:
- return rb_num_coerce_bin(x, y);
+ return rb_num_coerce_cmp(x, y);
}
return rb_dbl_cmp(a, b);
}
@@ -824,7 +847,7 @@ num_step(argc, argv, from)
}
}
else if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {
- const double epsilon = 2.2204460492503131E-16;
+ const double epsilon = DBL_EPSILON;
double beg = NUM2DBL(from);
double end = NUM2DBL(to);
double unit = NUM2DBL(step);
@@ -1322,7 +1345,7 @@ fix_cmp(x, y)
return INT2FIX(-1);
}
else {
- return rb_num_coerce_bin(x, y);
+ return rb_num_coerce_cmp(x, y);
}
}