0

I am rewriting an old Java 6 Program written to perform some scientific calculations in Java 8 and stuck up in this situation where I'm getting different results for rounding operation.

Java 6 is rounding an input like 0.499999999999999999994 to 1 but Java 8 is making it 0. I'm not able to understand the problem here.

For Instance:

private void foo() {
    System.out.println(Math.round(0.499999999999999999994));
}

The above code behaves differently for different Java versions.

It would be great if someone could shed some light on this issue.

2 Answers2

2

I think you stumbled on a known bug in Java 6 which was later fixed in Java 7. This explains the weird code behaviour in Java 6 and Java 8.

Bug Info:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6430675

More information and beautiful explanation by @OliverCharlesworth can be found in this post:

Why does Math.round(0.49999999999999994) return 1

Excerpt from his post:

In Java 6 (and presumably earlier), round(x) is implemented as floor(x+0.5). This is a specification bug, for precisely this one pathological case. Java 7 no longer mandates this broken implementation.

Community
  • 1
  • 1
user2004685
  • 9,548
  • 5
  • 37
  • 54
  • Thanks. Is there any fix for this? –  Jan 01 '17 at 00:04
  • Closing as duplicate question maybe more suitable then – weston Jan 01 '17 at 01:00
  • 2
    What do you mean fix @ShivamNegi? It is now fixed, so do you mean break it again in java 8, or apply the fix backwards to java 6? – weston Jan 01 '17 at 01:04
  • 3
    The fix is to fix your code and use Java 8. Period. Your old Java 6 compatible code is relying on a bug, and producing incorrect results. (If you have published results that are materially affected by this bug, then you should consider publishing a correction.) – Stephen C Jan 01 '17 at 01:20
1

The reason why the output of your example is 0 is a different one. 0.999999999999999999994 is a double. Casting an double to an it drops the decimal places of the double value.

public class Example {
    public static void main(String[] args) {
        double d1 = 0.9;
        Double D1 = Double.valueOf(d1);
        int d1AsInt = (int)d1;
        System.out.println("d1 as int:\t" + d1AsInt);
        System.out.println("d1 as int:\t" + D1.intValue());
    }
}

If you rely on precise values you should use BigDecimal and BigInteger.

Oliver
  • 3,815
  • 8
  • 35
  • 63
  • I'm sorry for confusing code. I'm seeing this behavior with `Math.round()` –  Jan 01 '17 at 00:10