summaryrefslogtreecommitdiff
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
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
-rw-r--r--ChangeLog7
-rw-r--r--numeric.c12
-rw-r--r--test/ruby/test_float.rb5
-rw-r--r--version.h6
4 files changed, 24 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 3e0ef09f87..c7edabb5ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Apr 30 22:24:25 2017 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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
+
Sun Apr 9 22:21:23 2017 NAKAMURA Usaku <usa@ruby-lang.org>
thread.c: rb_thread_fd_close [ci skip]
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:
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
index 3afd26d0b4..7d979a824f 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -442,6 +442,11 @@ class TestFloat < Test::Unit::TestCase
assert_raise(TypeError) {1.0.round(nil)}
def (prec = Object.new).to_int; 2; end
assert_equal(1.0, 0.998.round(prec))
+
+ assert_equal(+5.02, +5.015.round(2))
+ assert_equal(-5.02, -5.015.round(2))
+ assert_equal(+1.26, +1.255.round(2))
+ assert_equal(-1.26, -1.255.round(2))
end
VS = [
diff --git a/version.h b/version.h
index 4006cceb33..cab6d40e47 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.3.5"
-#define RUBY_RELEASE_DATE "2017-04-09"
-#define RUBY_PATCHLEVEL 303
+#define RUBY_RELEASE_DATE "2017-04-30"
+#define RUBY_PATCHLEVEL 304
#define RUBY_RELEASE_YEAR 2017
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 9
+#define RUBY_RELEASE_DAY 30
#include "ruby/version.h"