Why does adding a sum to a long value lead to a subtraction?

Michael Kemmerzell :

I encountered a troublesome issue and I can't really explain to myself why it is appearing.

Basically I want to add time to a timestamp (a simple long).

I understand it the following. If I add time to a timestamp I end in the future. If I subtract time to the timestamp I end in the past.

In my example it is the other way around. If I add something to my timestamp it is reduced and if I subtract something is added.

public class MyClass {
    public static void main(String args[]) {
      static final int MONTH_IN_SECONDS = 2629743;

      final long current = System.currentTimeMillis();
      System.out.println("Current: " + current);

      final long future = System.currentTimeMillis() + (MONTH_IN_SECONDS * 1000 * 3);
      System.out.println("Addition: " + future);

      final long past = System.currentTimeMillis() - (MONTH_IN_SECONDS * 1000 * 3);
      System.out.println("Subtraction: " + past);
    }
}

Result (compare the first 5 chars):

Current:     1582275101365
Addition:    1581574395774 // smaller than current even though it should be greater
Subtraction: 1582975806958 // great than current even though it should be smaller

Why does this happend? Does the term (MONTH_IN_SECONDS * 1000 * 3) overflow because it is only an Integer and thus the calculation does not work (or ends in a negative value)?

If I change the term to (MONTH_IN_SECONDS * 1000L * 3) it seems to work correctly. Is it because the complete term is casted to a long?

ernest_k :

The problem is here:

(MONTH_IN_SECONDS * 1000 * 3)

That's integer multiplication that's overflowing, and resulting in a negative number:

System.out.println((MONTH_IN_SECONDS * 1000 * 3));

That outputs -700705592. You'd have to declare MONTH_IN_SECONDS as long, or otherwise change the expression so that the result is long-typed.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=418754&siteId=1
Recommended