6 ответов:
Integer.MIN_VALUEи-2147483648, но самое высокое значение 32-разрядного целого числа может содержать+2147483647. Попытка представить+2147483648в 32-битном int будет эффективно "перевернуться" до-2147483648. Это связано с тем, что при использовании целых чисел со знаком они дополняют двоичные представления+2147483648и-2147483648идентичны. Это не проблема, однако, как+2147483648считается вне диапазона.Для немного больше чтения по этому вопросу, вы можете проверить статья в Википедии о дополнении двух.
поведение, на которое вы указываете, действительно, противоречит интуиции. Однако это поведение определяется javadoc для
Math.abs(int):если аргумент не отрицательный, аргумент возвращается. Если аргумент отрицательный, возвращается отрицание аргумента.
то есть
Math.abs(int)должен вести себя как следующий код Java:public static int abs(int x){ if (x >= 0) { return x; } return -x; }то есть, в отрицательном случае,
-x.по словам JLS раздел 15.15.4 на
-xравна(~x)+1, где~является побитовым оператором дополнения.чтобы проверить, правильно ли это звучит, давайте возьмем -1 в качестве примера.
целочисленное значение
-1можно отметить как0xFFFFFFFFв шестнадцатеричном формате на Java (проверьте это с помощьюprintlnили любой другой способ). Принимая выдает:-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1так, это завод.
давайте попробуем сейчас с
Integer.MIN_VALUE. Зная, что наименьшее целое число может быть представлено0x80000000, то есть, первый бит установлен в 1, а остальные 31 бит установлен в 0, то есть:-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUEи поэтому
Math.abs(Integer.MIN_VALUE)возвращаетInteger.MIN_VALUE. Также обратите внимание, что0x7FFFFFFFиInteger.MAX_VALUE.что сказал, как можно избежать проблем из-за этого контр-интуитивно понятный возвращаемое значение в будущем?
мы могли бы, как указал @Bombe, закидываем
intьlongраньше. Мы, однако, должны либо
- бросил их обратно в
ints, который не работает, потому чтоInteger.MIN_VALUE == (int) Math.abs((long)Integer.MIN_VALUE).- с
longS как-то надеется, что мы никогда не будем звонитьMath.abs(long)со значением, равнымLong.MIN_VALUE, так как у нас тоже естьMath.abs(Long.MIN_VALUE) == Long.MIN_VALUE.можно использовать
BigIntegers везде, потому чтоBigInteger.abs()действительно всегда возвращает положительное значение. Это хорошая альтернатива, жесткая немного медленнее, чем манипулирование необработанными целочисленными типами.мы можем написать нашу собственную оболочку для
Math.abs(int), например:/** * Fail-fast wrapper for {@link Math#abs(int)} * @param x * @return the absolute value of x * @throws ArithmeticException when a negative value would have been returned by {@link Math#abs(int)} */ public static int abs(int x) throws ArithmeticException { if (x == Integer.MIN_VALUE) { // fail instead of returning Integer.MAX_VALUE // to prevent the occurrence of incorrect results in later computations throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)"); } return Math.abs(x); }
- используйте целое побитовое число и очистите старший бит, гарантируя, что результат неотрицателен:
int positive = value & Integer.MAX_VALUE(по существу переполнение отInteger.MAX_VALUEдо0вместоInteger.MIN_VALUE)как финал обратите внимание, что эта проблема, похоже, известна в течение некоторого времени. См., например,эта запись о соответствующем правиле findbugs.
вот что говорит Java doc для математики.abs () in документация:
обратите внимание, что если аргумент равен значение Integer.MIN_VALUE, the большинство негативных представимое значение типа int , в результате получается то самое значение, которое отрицательный.
чтобы увидеть результат, который вы ожидаете, бросьте
Integer.MIN_VALUEtolong:System.out.println(Math.abs((long) Integer.MIN_VALUE));
2147483648 не может быть сохранен в виде целого числа в java, его двоичное представление совпадает с -2147483648.
но
(int) 2147483648L == -2147483648существует одно отрицательное число, которое не имеет положительного эквивалента, поэтому для него нет положительного значения. Вы увидите то же самое поведение с лонгом.МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ.
Comments