summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-04-30 13:27:17 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-04-30 13:27:17 +0000
commit2dfde7e8586cf35318b6053410dba74fe9f06f8d (patch)
tree88dd570d10081c9e48d7302aa36d8ca2cf644215 /numeric.c
parent44e329ea7f2926764bdd33807cde2a2b16d55d1d (diff)
merge revision(s) 55604,55612: [Backport #13138]
* 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 numeric.c: round as double * numeric.c (flo_round): compare as double, not long double with i387. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@58513 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/numeric.c b/numeric.c
index ca961d8d6c..c1c673927c 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1786,7 +1786,7 @@ static VALUE
flo_round(int argc, VALUE *argv, VALUE num)
{
VALUE nd;
- double number, f;
+ double number, f, x;
int ndigits = 0;
int binexp;
enum {float_dig = DBL_DIG+2};
@@ -1828,8 +1828,14 @@ flo_round(int argc, VALUE *argv, VALUE num)
return DBL2NUM(0);
}
f = pow(10, ndigits);
- return DBL2NUM(round(number * f) / f);
-}
+ x = round(number * f);
+ if (x > 0) {
+ if ((double)((x + 0.5) / f) <= number) x += 1;
+ }
+ else {
+ if ((double)((x - 0.5) / f) >= number) x -= 1;
+ }
+ return DBL2NUM(x / f);}
/*
* call-seq: