Как операторы ‹ или › могут переполняться?

Я заинтригован следующим утверждением, найденным в документации метода System.nanoTime() в Java:

long t0 = System.nanoTime();

...

long t1 = System.nanoTime();

Следует использовать t1 - t0 < 0, а не t1 < t0 из-за возможности числового переполнения.

Источник: http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime()

Почему t1 < t0 может "переполниться"? Это есть в Javadocs, но я думаю, что это применимо к любому языку.


person Bitcoin Cash - ADA enthusiast    schedule 15.07.2014    source источник
comment
ответ здесь. -java" title="почему я должен использовать t1 t0 0, а не t1 t0 при использовании системы nanotime в java"> stackoverflow.com/questions/18414059/   -  person Ruchira Gayan Ranaweera    schedule 15.07.2014


Ответы (2)


Дело не в том, что < может переполниться, а в том, что t2 может переполниться.

Примеры в шестнадцатеричном формате, потому что переполнение очевидно в шестнадцатеричном формате.

Допустим, вы звоните System.nanoTime(), а результат 0x7FFFFFFF00000000. Это очень близко к максимальному значению long. Это t1.

Через несколько секунд вы вызываете его снова и получаете 0x8000000011111111. Это очень близко к минимальному значению long, что означает, что оно намного меньше, чем первое значение, которое вы получили! Это t2.

Если вы отметите t2 < t1, вы получите false, потому что t2 действительно меньше t1.

Если вычислить разницу t2 - t1, это тоже переполнение, но бывает, что это всегда отменяет первое переполнение (если оно было). В результате получается 0x0000000111111111, что является правильной разницей во времени. Это больше 0, поэтому t2 - t1 > 0 возвращает true.

person user253751    schedule 15.07.2014
comment
@DavidWallace, тогда ваши расчеты неверны; это будет проблемой в 2306 или ранее. Помните, что это 2 ^ 64 наносекунд. - person user253751; 15.07.2014

В дополнение к тому, что сказал immibis, этот источник объясняет разницу между a ‹ b и a-b ‹ 0 с помощью big long:

    long t1 = Long.MAX_VALUE;
    long t2 = Long.MIN_VALUE;
    //should have the same result with small longs, but is different when rotating from max value to min value of Long
    System.out.println(t1 - t2 < 0); //true
    System.out.println(t1 < t2); //false

    //should have the same result
    System.out.println(t1 - t2 > 0); // false
    System.out.println(t1 > t2); //true

    System.out.println(t2 - t1); // 1 => 1 nanosecond of difference

Поскольку время в наносекунде может превышать «длинный» размер, когда время достигает максимального значения, оно снова начинается с минимального значения. Таким образом, разница между MAX_VALUE и MIN_VALUE составляет 1 наносекунду.

person pdem    schedule 15.07.2014