-9

So I narrowed down a bug in my application to java messing up a simple subtraction calculation. I can't figure out why exactly. Here is the bit of code:

    for (double x = (((double)bdl.length())-1)/10; x > 0; x--) {
            int count;
            System.out.println("x = " + x);
            if (x >= 1) {
                System.out.println("X = " + x + " so count = 20");
                count = (20);
            } else {
                count = (int)(x*20);
                System.out.println("X = " + x + " so count = "+count);
            }
    }

The variable bdl is just a JSONArray, which I am only concerned with its length at this point. As bdl comes in initially it has length 15, so x will equal 1.4 . The first time through the loop the first println says "X = 1.4 so count = 20" which is correct. The second time through however when x should = 0.4, it instead says "X = 0.3999999999999999 so count = 7". I understand that casting (x*20) to an int at that point and time will give me 7, but my question is Why is x not equal to 0.4 .

user2864740
  • 60,010
  • 15
  • 145
  • 220
Danny
  • 21
  • 2
  • 8
  • 16
    ObReference: [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Miserable Variable Jan 09 '14 at 20:20
  • 7
    You should know what is the correct type to use before blaming Java. – Diogo Moreira Jan 09 '14 at 20:21
  • 1
    This is due to floating point arithmetic. You can try to round the answer to a certain number of decimal spots if it bothers you or just truncate. – telkins Jan 09 '14 at 20:21
  • 1
    http://stackoverflow.com/questions/322749/retain-precision-with-doubles-in-java , http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results – user2864740 Jan 09 '14 at 20:23

2 Answers2

1

You're using a double, which is a floating-point number. This is not meant for presision, moreover, it is meant for speed and non-precision. So instead, you should be using an int, like this:

for (int x = ((bdl.length())-1)/10; x > 0; x--) {

This will keep your numbers precise.

hichris123
  • 10,145
  • 15
  • 56
  • 70
0

Actually, your 'x' does equal 0.4, it's only a matter of precision.
All floating point comparison operations should be executed with a certain precision (delta or epsilon in some implementations).

Refer to this post.

Community
  • 1
  • 1
VitaliG
  • 52
  • 3