summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-02-01 03:12:21 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-02-01 03:12:21 +0000
commite4b53b22228d935847b72e8f9ab0f49a15b54215 (patch)
treeae6cd78921bf626d54145b5485474bf59c3dceb4 /numeric.c
parent005f12582975d8382851b740690f97dba35aaa2a (diff)
2000-02-01
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@611 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/numeric.c b/numeric.c
index 20dff3a833..0169621623 100644
--- a/numeric.c
+++ b/numeric.c
@@ -331,8 +331,7 @@ flo_modulo(x, y, modulo)
result = value1 - value2 * value;
}
#endif
- if (modulo &&
- (RFLOAT(x)->value < 0.0) != (result < 0.0) && result != 0.0) {
+ if (modulo && value*result<0.0) {
result += value;
}
return rb_float_new(result);
@@ -353,6 +352,45 @@ flo_remainder(x, y)
}
static VALUE
+flo_divmod(x, y)
+ VALUE x, y;
+{
+ double value, div, mod;
+
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ value = (double)FIX2LONG(y);
+ break;
+ case T_BIGNUM:
+ value = rb_big2dbl(y);
+ break;
+ case T_FLOAT:
+ value = RFLOAT(y)->value;
+ break;
+ default:
+ return rb_num_coerce_bin(x, y);
+ }
+
+#ifdef HAVE_FMOD
+ mod = fmod(RFLOAT(x)->value, value);
+#else
+ {
+ double value1 = RFLOAT(x)->value;
+ double value2;
+
+ modf(value1/value, &value2);
+ mod = value1 - value2 * value;
+ }
+#endif
+ div = (RFLOAT(x)->value - mod) / value;
+ if (value*mod<0.0) {
+ mod += value;
+ div -= 1.0;
+ }
+ return rb_assoc_new(rb_float_new(div), rb_float_new(mod));
+}
+
+static VALUE
flo_pow(x, y)
VALUE x, y;
{
@@ -1517,6 +1555,7 @@ Init_Numeric()
rb_define_method(rb_cFloat, "*", flo_mul, 1);
rb_define_method(rb_cFloat, "/", flo_div, 1);
rb_define_method(rb_cFloat, "%", flo_mod, 1);
+ rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
rb_define_method(rb_cFloat, "remainder", flo_remainder, 1);
rb_define_method(rb_cFloat, "**", flo_pow, 1);
rb_define_method(rb_cFloat, "==", flo_eq, 1);