Мерцающие самолеты

Хехе, любопытно. Я думаю, что это «намеренная ошибка», так сказать.

Основная причина заключается в том, как записывается класс Integer. В принципе, parseInt «оптимизирован» для положительных чисел. Когда он анализирует строку, он создает результат кумулятивно, но отрицается. Затем он переворачивает знак конечного результата.

Пример:

66 = 0x42

разобран как:

4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)

-64 - 2 = -66 (hex 2 parsed)

return -66 * (-1) = 66

Теперь рассмотрим ваш пример FFFF8000

16*(-1) = -16 (first F parsed)
-16*16 = -256 

-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352 

-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888

-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464 

-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552 

-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728). 
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.

Редактирование (добавление): для того, чтобы parseInt () работал «последовательно» для -Integer.MAX_VALUE & lt; = n & lt; = Integer.MAX_VALUE , им пришлось бы реализовать логику для «поворота» при достижении -Integer.MAX_VALUE в кумулятивном результате, начиная с максимального конца целочисленного диапазона и продолжая вниз оттуда. Почему они этого не сделали, нужно было бы спросить Джоша Блоха или того, кто его осуществил в первую очередь. Это может быть просто оптимизация.

Однако,

Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));

работает просто отлично, по этой причине. В источнике для Integer вы можете найти этот комментарий.

// Accumulating negatively avoids surprises near MAX_VALUE
13
задан eoaksnes 22 July 2013 в 11:43
поделиться