From: "shyouhei (Shyouhei Urabe)" Date: 2012-09-20T10:52:56+09:00 Subject: [ruby-core:47613] [ruby-trunk - Bug #7037] float formatting inconsistently rounds half to even Issue #7037 has been updated by shyouhei (Shyouhei Urabe). It seems Ruby is just following C here. zsh % cat tmp.c #include #include int main(void) { printf("%1.1f\n", 1.05); printf("%1.1f\n", 1.15); printf("%1.1f\n", 1.25); printf("%1.1f\n", 1.35); printf("%1.1f\n", 1.45); printf("%1.1f\n", 1.55); printf("%1.1f\n", 1.65); printf("%1.1f\n", 1.75); printf("%1.1f\n", 1.85); printf("%1.1f\n", 1.95); return EXIT_SUCCESS; } zsh % gcc tmp.c zsh % ./a.out 1.1 1.1 1.2 1.4 1.4 1.6 1.6 1.8 1.9 1.9 so I think, no this is not a part of our spec. This is just machine-dependent. Strictly specifying this behaviour would not make both C/JRuby people happy. ---------------------------------------- Bug #7037: float formatting inconsistently rounds half to even https://bugs.ruby-lang.org/issues/7037#change-29564 Author: headius (Charles Nutter) Status: Closed Priority: Normal Assignee: Category: core Target version: ruby -v: 2.0.0dev MRI does not appear to consistently round half to even. I'm not sure what rounding strategy this is, but it rounds xx05 and xx15 to odd for xxx, and other values to even: irb(main):001:0> "%1.1f" % 1.05 => "1.1" irb(main):002:0> "%1.1f" % 1.15 => "1.1" irb(main):003:0> "%1.1f" % 1.25 => "1.2" irb(main):004:0> "%1.1f" % 1.35 => "1.4" irb(main):005:0> "%1.1f" % 1.45 => "1.4" irb(main):006:0> "%1.1f" % 1.55 => "1.6" None of the tie-breaking strategies I could find (http://en.wikipedia.org/wiki/Rounding#Tie-breaking) seem to support MRI's model. If MRI is indeed using "half even", xx05 should round to xx0 and xx15 should round to xx2. An example with Java's BigDecimal appears to support this: irb(main):029:0> java.math.BigDecimal.new('1.05').round(java.math.MathContext.new(2, java.math.RoundingMode::HALF_EVEN)).to_s => "1.0" irb(main):030:0> java.math.BigDecimal.new('1.15').round(java.math.MathContext.new(2, java.math.RoundingMode::HALF_EVEN)).to_s => "1.2" irb(main):031:0> java.math.BigDecimal.new('1.25').round(java.math.MathContext.new(2, java.math.RoundingMode::HALF_EVEN)).to_s => "1.2" irb(main):032:0> java.math.BigDecimal.new('1.35').round(java.math.MathContext.new(2, java.math.RoundingMode::HALF_EVEN)).to_s => "1.4" We would like clarification about the proper rounding tie-breaker strategy to use so we can fix this JRuby issue properly: http://jira.codehaus.org/browse/JRUBY-6889 -- http://bugs.ruby-lang.org/