diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-03 07:09:48 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-03 07:09:48 +0000 |
commit | c32b77cee1ead76eafb05604d49b315217c49d49 (patch) | |
tree | a5944d3699f97c0ec42192d67aa9f9b352188ef8 | |
parent | ce8d9b4a0d2c16ff2d634ce6c4b00a9156cc55f3 (diff) | |
download | ruby-c32b77cee1ead76eafb05604d49b315217c49d49.tar.gz |
* numeric.c (fix_minus, fix_mul, fix_quo, fix_div, fix_mod,
fix_divmod, fix_pow): ditto.
* numeric.c (fix_plus): reduce coercing when a method knows about
a operand type. [ruby-dev:26723]
* bignum.c (rb_big_div, rb_big_modulo): export to reduce
coercing.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | bignum.c | 4 | ||||
-rw-r--r-- | intern.h | 2 | ||||
-rw-r--r-- | numeric.c | 90 |
4 files changed, 91 insertions, 16 deletions
@@ -1,3 +1,14 @@ +Wed Aug 3 12:40:28 2005 Tadashi Saito <shiba@mail2.accsnet.ne.jp> + + * numeric.c (fix_minus, fix_mul, fix_quo, fix_div, fix_mod, + fix_divmod, fix_pow): ditto. + + * numeric.c (fix_plus): reduce coercing when a method knows about + a operand type. [ruby-dev:26723] + + * bignum.c (rb_big_div, rb_big_modulo): export to reduce + coercing. + Wed Aug 3 10:13:52 2005 NAKAMURA Usaku <usa@ruby-lang.org> * configure.in, {bcc32,win32,wince}/Makefile.sub (HAVE_SNPRINTF, @@ -1424,7 +1424,7 @@ bigdivmod(x, y, divp, modp) * Divides big by other, returning the result. */ -static VALUE +VALUE rb_big_div(x, y) VALUE x, y; { @@ -1458,7 +1458,7 @@ rb_big_div(x, y) * information. */ -static VALUE +VALUE rb_big_modulo(x, y) VALUE x, y; { @@ -98,6 +98,8 @@ double rb_big2dbl _((VALUE)); VALUE rb_big_plus _((VALUE, VALUE)); VALUE rb_big_minus _((VALUE, VALUE)); VALUE rb_big_mul _((VALUE, VALUE)); +VALUE rb_big_div _((VALUE, VALUE)); +VALUE rb_big_modulo _((VALUE, VALUE)); VALUE rb_big_divmod _((VALUE, VALUE)); VALUE rb_big_pow _((VALUE, VALUE)); VALUE rb_big_and _((VALUE, VALUE)); @@ -1985,10 +1985,14 @@ fix_plus(x, y) } return r; } - if (TYPE(y) == T_FLOAT) { + switch (TYPE(y)) { + case T_BIGNUM: + return rb_big_plus(y, x); + case T_FLOAT: return rb_float_new((double)FIX2LONG(x) + RFLOAT(y)->value); + default: + return rb_num_coerce_bin(x, y); } - return rb_num_coerce_bin(x, y); } /* @@ -2018,10 +2022,15 @@ fix_minus(x, y) } return r; } - if (TYPE(y) == T_FLOAT) { + switch (TYPE(y)) { + case T_BIGNUM: + x = rb_int2big(FIX2LONG(x)); + return rb_big_minus(x, y); + case T_FLOAT: return rb_float_new((double)FIX2LONG(x) - RFLOAT(y)->value); + default: + return rb_num_coerce_bin(x, y); } - return rb_num_coerce_bin(x, y); } /* @@ -2053,10 +2062,14 @@ fix_mul(x, y) } return r; } - if (TYPE(y) == T_FLOAT) { + switch (TYPE(y)) { + case T_BIGNUM: + return rb_big_mul(y, x); + case T_FLOAT: return rb_float_new((double)FIX2LONG(x) * RFLOAT(y)->value); + default: + return rb_num_coerce_bin(x, y); } - return rb_num_coerce_bin(x, y); } static void @@ -2107,7 +2120,14 @@ fix_quo(x, y) if (FIXNUM_P(y)) { return rb_float_new((double)FIX2LONG(x) / (double)FIX2LONG(y)); } - return rb_num_coerce_bin(x, y); + switch (TYPE(y)) { + case T_BIGNUM: + return rb_float_new((double)FIX2LONG(y) / rb_big2dbl(y)); + case T_FLOAT: + return rb_float_new((double)FIX2LONG(x) / RFLOAT(y)->value); + default: + return rb_num_coerce_bin(x, y); + } } /* @@ -2130,7 +2150,15 @@ fix_div(x, y) fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0); return LONG2NUM(div); } - return rb_num_coerce_bin(x, y); + switch (TYPE(y)) { + case T_BIGNUM: + x = rb_int2big(FIX2LONG(x)); + return rb_big_div(x, y); + case T_FLOAT: + return rb_Integer(rb_float_new((double)FIX2LONG(x) / RFLOAT(y)->value)); + default: + return rb_num_coerce_bin(x, y); + } } /* @@ -2152,7 +2180,20 @@ fix_mod(x, y) fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod); return LONG2NUM(mod); } - return rb_num_coerce_bin(x, y); + switch (TYPE(y)) { + case T_BIGNUM: + x = rb_int2big(FIX2LONG(x)); + return rb_big_modulo(x, y); + case T_FLOAT: + { + double mod; + + flodivmod((double)FIX2LONG(x), RFLOAT(y)->value, 0, &mod); + return rb_float_new(mod); + } + default: + return rb_num_coerce_bin(x, y); + } } /* @@ -2172,7 +2213,23 @@ fix_divmod(x, y) return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod)); } - return rb_num_coerce_bin(x, y); + switch (TYPE(y)) { + case T_BIGNUM: + x = rb_int2big(FIX2LONG(x)); + return rb_big_divmod(x, y); + case T_FLOAT: + { + double div, mod; + volatile VALUE a, b; + + flodivmod((double)FIX2LONG(x), RFLOAT(y)->value, &div, &mod); + a = rb_float_new(div); + b = rb_float_new(mod); + return rb_assoc_new(a, b); + } + default: + return rb_num_coerce_bin(x, y); + } } /* @@ -2202,11 +2259,16 @@ fix_pow(x, y) return rb_big_pow(rb_int2big(a), y); } return rb_float_new(pow((double)a, (double)b)); - } else if (TYPE(y) == T_FLOAT) { - long a = FIX2LONG(x); - return rb_float_new(pow((double)a, RFLOAT(y)->value)); } - return rb_num_coerce_bin(x, y); + switch (TYPE(y)) { + case T_BIGNUM: + x = rb_int2big(FIX2LONG(x)); + return rb_big_pow(x, y); + case T_FLOAT: + return rb_float_new(pow((double)FIX2LONG(x), RFLOAT(y)->value)); + default: + return rb_num_coerce_bin(x, y); + } } /* |