Как операторы "<" или ">" могут переполниться?
Я заинтригован следующим утверждением, найденным в документации метода 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
Почему это так t1 < t0
может "переполниться"? Это в Javadocs, но я думаю, что это относится к любому языку.
2 ответа
Это не то <
может переполниться, это то, что t2
может переполниться.
Примеры в шестнадцатеричном, потому что переполнение очевидно в шестнадцатеричном.
Скажи, что ты звонишь System.nanoTime()
и результат 0x7FFFFFFF00000000
, Это очень близко к максимальному значению long
, Это t1
,
Через несколько секунд вы звоните снова и получаете 0x8000000011111111
, Это очень близко к минимальному значению long
- это означает, что он намного меньше, чем первое полученное вами значение! Это t2
,
Если вы проверили t2 < t1
, вы получите false
, так как t2
действительно меньше, чем t1
,
Если вы рассчитываете разницу t2 - t1
это также переполняет, но бывает, что это всегда отменяет первое переполнение (если оно было). Результат 0x0000000111111111
которая является правильной разницей во времени. Это больше 0, так t2 - t1 > 0
возвращается true
,
В дополнение к тому, что сказал immibis, этот источник объясняет разницу между a 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 наносекунду.