From 931614a341b3113efd41893d1a95b22073dc2f68 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 5 Jun 2007 05:31:05 +0000 Subject: * numeric.c (int_round): should not just truncate. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12437 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- numeric.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'numeric.c') diff --git a/numeric.c b/numeric.c index 5f9b98e413..ceaba65fee 100644 --- a/numeric.c +++ b/numeric.c @@ -2308,22 +2308,6 @@ int_pow(long x, unsigned long y) return LONG2NUM(z); } -static VALUE -int_round(int argc, VALUE* argv, VALUE num) -{ - VALUE nd; - int ndigits; - - if (argc == 0) return num; - rb_scan_args(argc, argv, "1", &nd); - ndigits = NUM2INT(nd); - if (ndigits > 0) { - return rb_Float(num); - } - ndigits = -ndigits; - return rb_funcall(num, '-', 1, rb_funcall(num, '%', 1, int_pow(10, ndigits))); -} - /* * call-seq: * fix ** other => Numeric @@ -2911,6 +2895,31 @@ int_dotimes(VALUE num) return num; } +static VALUE +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); + + rb_scan_args(argc, argv, "1", &n); + ndigits = NUM2INT(n); + if (ndigits > 0) { + return rb_Float(num); + } + ndigits = -ndigits; + f = int_pow(10, ndigits); + h = rb_funcall(f, '/', 1, INT2FIX(2)); + r = rb_funcall(num, '%', 1, f); + n = rb_funcall(num, '-', 1, r); + if (!RTEST(rb_funcall(r, '<', 1, h))) { + n = rb_funcall(n, '+', 1, f); + } + return n; +} + /* * call-seq: * fix.zero? => true or false -- cgit v1.2.3