diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-29 06:44:01 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-29 06:44:01 +0000 |
commit | 3b5eac1a0844ecd4ab5bd937f2ca9bd7b984441e (patch) | |
tree | 69d93bc184dd8e6862f0e1739c8b4b948f1ebf10 /numeric.c | |
parent | f35974066131e8c5517abc1cad366780bd90cf43 (diff) | |
download | ruby-3b5eac1a0844ecd4ab5bd937f2ca9bd7b984441e.tar.gz |
* numeric.c (fix_pow): get rid of division by zero. reported by
Yusuke ENDOH <mame AT tsg.ne.jp> [ruby-dev:31040]
* numeric.c (int_round): do nothing when rounding by zeroth digit.
check underflow. [ruby-dev:31043]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12661 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -2330,6 +2330,7 @@ fix_pow(VALUE x, VALUE y) if (b == 0) return INT2FIX(1); if (b == 1) return x; a = FIX2LONG(x); + if (a == 0) return INT2FIX(0); if (b > 0) { return int_pow(a, b); } @@ -2901,16 +2902,28 @@ int_round(int argc, VALUE* argv, VALUE num) VALUE n, f, h, r; int ndigits; - if (argc == 0) return num; - if (FIXNUM_P(num)) return num_round(argc, argv, num); - + if (argc == 0) return 0; rb_scan_args(argc, argv, "1", &n); ndigits = NUM2INT(n); if (ndigits > 0) { return rb_Float(num); } + if (ndigits == 0) { + return num; + } ndigits = -ndigits; + if (ndigits < 0) { + rb_raise(rb_eArgError, "ndigits out of range"); + } f = int_pow(10, ndigits); + if (FIXNUM_P(num) && FIXNUM_P(f)) { + SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f); + int neg = x < 0; + if (neg) x = -x; + x = (x + y / 2) / y * y; + if (neg) x = -x; + return LONG2NUM(x); + } h = rb_funcall(f, '/', 1, INT2FIX(2)); r = rb_funcall(num, '%', 1, f); n = rb_funcall(num, '-', 1, r); |