summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-06-05 05:31:05 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-06-05 05:31:05 +0000
commit931614a341b3113efd41893d1a95b22073dc2f68 (patch)
treeb7dbb7ebb5d4ef1201e8d3ef97a52891e6bab3e1 /numeric.c
parent3c175900610215905772fc27cd63d3c7bf2d41f8 (diff)
* 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
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c41
1 files changed, 25 insertions, 16 deletions
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