简体   繁体   中英

Java double to long conversion error mystery

Could someone please explain something to me.

    public static void main(String[] args) {

    long a = 0;
    long b = 0;
    Random r = ThreadLocalRandom.current();

    for (int i = 0; i < 1000; i++) {
        double d = r.nextDouble()*(r.nextBoolean() ? 1.0 : -1.0);

        a += d*100;
        b += (long)(100*d);
        //System.out.println(a + " " + b + " " + d);

    }

    System.out.println(a);
    System.out.println(b);
    }

Why is a.= b at the end of this loop? Is it a glitch in the matrix, If I remove the random signing of "d". then a == b? Why?

What happens here is what is rounded.

Your assignments:

a += d*100
b += (long)(100*d);

Will be executed as:

a = (long)(a + d * 100);
b = b + (long)(100 * d);

After one loop a and b can be different when a and b are positive while d is negative or vice versa. When adding d*100 to a, you are adding exact value (for example -1.1) while in case of b, it will be rounded first to -1. Let's take an example. At the start of the loop we will have those values:

a = b = 1024
d = -0.178

the end result of single run will be:

a = (long)(1024-17.8) = (long)(1006.2) = 1006
b = 1024-(long)17.8 = 1024-17 = 1007

According to the Java Spec += is specified like this:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

That means that your two statements

  a += d*100;
  b += (long)(100*d);

are basically equivalent to

  a = (long) (a + d*100);
  b = (long) (b + (long)(100*d));

In the case of a the addition is between a long value and a double value, so the whole calculation will be done in the double realm.

In the case of b both parts of the addition are long values, so the calculation will use long maths.

Due to the fact that long and double have different value ranges the results can differ.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM