Почему добавление суммы к длинному значению приводит к вычитанию? - PullRequest
1 голос
/ 21 февраля 2020

Я столкнулся с неприятной проблемой, и я не могу объяснить себе, почему она появляется.

В основном я хочу добавить время к метке времени (простой long).

I понять это следующим образом. Если я добавлю время к временной метке, я закончу в будущем. Если я вычитаю время из метки времени, я заканчиваю в прошлом.

В моем примере все наоборот. Если я добавляю что-то к своей отметке времени, она уменьшается, а если я вычитаю что-то, добавляется.

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);
    }
}

Результат (сравните первые 5 символов):

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

Почему это происходит? Переполнен ли термин (MONTH_IN_SECONDS * 1000 * 3), потому что это всего лишь целое число и, следовательно, расчет не работает (или заканчивается отрицательным значением)?

Если я изменю термин на (MONTH_IN_SECONDS * 1000L * 3), то, похоже, он будет работать правильно. Это потому, что полный термин приведен к long?

Ответы [ 2 ]

3 голосов
/ 21 февраля 2020

Переполнен ли термин (MONTH_IN_SECONDS *1000* 3), потому что он является только целым числом и, следовательно, расчет не работает (или заканчивается отрицательным значением)?

Месяц в секунд? Гугл говорит 2 630 000. (Хотя я вижу, что у вас 2629743.)

    2,630,000 * 1000 * 3 = 7,890,000,000

Integer.MAX_VALUE = 2^31 = 2,147,483,648

Так что да, это целочисленное переполнение .

3 голосов
/ 21 февраля 2020

Проблема здесь:

(MONTH_IN_SECONDS * 1000 * 3)

Это целочисленное умножение, которое переполняется и приводит к отрицательному числу:

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

Это выводит -700705592. Вам нужно было бы объявить MONTH_IN_SECONDS как long или иначе изменить выражение так, чтобы результат был long -тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...