diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-07 07:37:55 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-07-07 07:37:55 +0000 |
commit | 0229f70039a4eab72d3a007e4fde2af8935d750b (patch) | |
tree | 0ab24af61bc3fe18bd6fccc658fd2350a03c5984 /numeric.c | |
parent | 5d339a32e88dce014a315d7ce791332d6814c693 (diff) | |
download | ruby-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.c | 11 |
1 files changed, 9 insertions, 2 deletions
@@ -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 |