diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-02-01 03:12:21 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-02-01 03:12:21 +0000 |
commit | e4b53b22228d935847b72e8f9ab0f49a15b54215 (patch) | |
tree | ae6cd78921bf626d54145b5485474bf59c3dceb4 /numeric.c | |
parent | 005f12582975d8382851b740690f97dba35aaa2a (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.c | 43 |
1 files changed, 41 insertions, 2 deletions
@@ -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); |