aboutsummaryrefslogtreecommitdiffstats
path: root/numeric.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-07 07:37:55 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-07 07:37:55 +0000
commit0229f70039a4eab72d3a007e4fde2af8935d750b (patch)
tree0ab24af61bc3fe18bd6fccc658fd2350a03c5984 /numeric.c
parent5d339a32e88dce014a315d7ce791332d6814c693 (diff)
downloadruby-0229f70039a4eab72d3a007e4fde2af8935d750b.tar.gz
numeric.c: round nearly middle value
* numeric.c (flo_round): [EXPERIMENTAL] adjust the case that the receiver is close to the exact but unrepresentable middle value of two values in the given precision. http://d.hatena.ne.jp/hnw/20160702 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55604 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/numeric.c b/numeric.c
index c92b7b430b..b806ceca3c 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1990,7 +1990,7 @@ rb_int_truncate(VALUE num, int ndigits)
static VALUE
flo_round(int argc, VALUE *argv, VALUE num)
{
- double number, f;
+ double number, f, x;
int ndigits = 0;
if (rb_check_arity(argc, 0, 1)) {
@@ -2005,7 +2005,14 @@ flo_round(int argc, VALUE *argv, VALUE num)
}
if (float_invariant_round(number, ndigits, &num)) return num;
f = pow(10, ndigits);
- return DBL2NUM(round(number * f) / f);
+ x = round(number * f);
+ if (x > 0) {
+ if ((x + 0.5) / f <= number) x += 1;
+ }
+ else {
+ if ((x - 0.5) / f >= number) x -= 1;
+ }
+ return DBL2NUM(x / f);
}
static int