[前][次][番号順一覧][スレッド一覧]

ruby-changes:43531

From: nobu <ko1@a...>
Date: Thu, 7 Jul 2016 16:38:00 +0900 (JST)
Subject: [ruby-changes:43531] nobu:r55604 (trunk): numeric.c: round nearly middle value

nobu	2016-07-07 16:37:55 +0900 (Thu, 07 Jul 2016)

  New Revision: 55604

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55604

  Log:
    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

  Modified files:
    trunk/ChangeLog
    trunk/numeric.c
    trunk/test/ruby/test_float.rb
Index: numeric.c
===================================================================
--- numeric.c	(revision 55603)
+++ numeric.c	(revision 55604)
@@ -1990,7 +1990,7 @@ rb_int_truncate(VALUE num, int ndigits) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1990
 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 n https://github.com/ruby/ruby/blob/trunk/numeric.c#L2005
     }
     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
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55603)
+++ ChangeLog	(revision 55604)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jul  7 16:37:53 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* 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
+
 Thu Jul  7 16:31:07 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* io.c (rb_io_s_foreach, rb_io_s_readlines): convert arguments
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 55603)
+++ test/ruby/test_float.rb	(revision 55604)
@@ -447,6 +447,11 @@ class TestFloat < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_float.rb#L447
     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
 
   def test_floor_with_precision

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]