ruby-changes:44484
From: nobu <ko1@a...>
Date: Fri, 4 Nov 2016 16:32:01 +0900 (JST)
Subject: [ruby-changes:44484] nobu:r56557 (trunk): util.c: round to even
nobu 2016-11-04 16:31:47 +0900 (Fri, 04 Nov 2016) New Revision: 56557 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56557 Log: util.c: round to even * util.c (ruby_dtoa): round to even, instead of rounding to nearest. [ruby-core:77864] [Bug #12889] Modified files: trunk/ChangeLog trunk/test/ruby/test_sprintf.rb trunk/util.c Index: util.c =================================================================== --- util.c (revision 56556) +++ util.c (revision 56557) @@ -3165,7 +3165,7 @@ ruby_dtoa(double d_, int mode, int ndigi https://github.com/ruby/ruby/blob/trunk/util.c#L3165 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; + spec_case, try_quick, half = 0; Long L; #ifndef Sudden_Underflow int denorm; @@ -3452,17 +3452,17 @@ ruby_dtoa(double d_, int mode, int ndigi https://github.com/ruby/ruby/blob/trunk/util.c#L3452 ilim = i; *s++ = '0' + (int)L; if (i == ilim) { - double x; if (dval(d) > 0.5 + dval(eps)) goto bump_up; - else if (!isinf(x = d_ * tens[ilim-1] + 0.5) && - dval(d) > modf(x, &x)) - goto bump_up; else if (dval(d) < 0.5 - dval(eps)) { while (*--s == '0') ; s++; goto ret1; } + half = 1; + if ((*(s-1) - '0') & 1) { + goto bump_up; + } break; } } @@ -3770,12 +3770,13 @@ keep_dig: https://github.com/ruby/ruby/blob/trunk/util.c#L3770 *s++ = '1'; goto ret; } - ++*s++; + if (!half || (*s - '0') & 1) + ++*s; } else { while (*--s == '0') ; - s++; } + s++; ret: Bfree(S); if (mhi) { Index: test/ruby/test_sprintf.rb =================================================================== --- test/ruby/test_sprintf.rb (revision 56556) +++ test/ruby/test_sprintf.rb (revision 56557) @@ -283,7 +283,16 @@ class TestSprintf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_sprintf.rb#L283 end def test_float_prec - assert_equal("5.03", sprintf("%.2f",5.025)) + assert_equal("5.00", sprintf("%.2f",5.005)) + assert_equal("5.02", sprintf("%.2f",5.015)) + assert_equal("5.02", sprintf("%.2f",5.025)) + assert_equal("5.04", sprintf("%.2f",5.035)) + bug12889 = '[ruby-core:77864] [Bug #12889]' + assert_equal("1234567892", sprintf("%.0f", 1234567891.99999)) + assert_equal("1234567892", sprintf("%.0f", 1234567892.49999)) + assert_equal("1234567892", sprintf("%.0f", 1234567892.50000)) + assert_equal("1234567894", sprintf("%.0f", 1234567893.50000)) + assert_equal("1234567892", sprintf("%.0f", 1234567892.00000), bug12889) end BSIZ = 120 Index: ChangeLog =================================================================== --- ChangeLog (revision 56556) +++ ChangeLog (revision 56557) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Nov 4 16:31:45 2016 Nobuyoshi Nakada <nobu@r...> + + * util.c (ruby_dtoa): round to even, instead of rounding to + nearest. [ruby-core:77864] [Bug #12889] + Fri Nov 4 15:31:00 2016 NARUSE, Yui <naruse@r...> * configure.in: Add compiler version message into rbconfig -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/