Как 0x80000000 приравнивается к -2147483648 в Java?

Взяв двоичный файл 0x80000000, мы получаем

1000 0000 0000 0000 0000 0000 0000 0000

Как это соответствует -2147483648. Я получил этот вопрос с этой программой.

class a
{
        public static void main(String[] args)
        {
                int a = 0x80000000;
                System.out.printf("%x %d\n",a,a);
        }
}

meow@VikkyHacks:~/Arena/java$ java a
80000000 -2147483648

EDIT Я узнал, что дополнение 2 используется для представления отрицательных чисел. Когда я пытаюсь приравнять это к тому, что 1 дополнение будет

1's Comp. :: 0111 1111 1111 1111 1111 1111 1111 1111
2's Comp. :: 1000 0000 0000 0000 0000 0000 0000 0000

что опять же не имеет никакого смысла, как 0x80000000 равняется -2147483648


person vikkyhacks    schedule 15.09.2013    source источник
comment
Как вы вообще получили 0x80000000 от -2147483648?   -  person Matt Ball    schedule 15.09.2013
comment
@MattBall Спасибо, мне нужно отредактировать свой вопрос !!!   -  person vikkyhacks    schedule 15.09.2013
comment
Вы уже ответили на свой вопрос в своем вопросе только перед редактированием. Обратите внимание на дополнение 2.   -  person Rohit Jain    schedule 15.09.2013
comment
Для «a» как целого числа со знаком вывод выглядит правильно. Максимальное положительное целое число равно 2147383647: или 0x7FFFFFFFF. Если вы добавите 1 к максимуму, он переполнится с точки зрения подписанной единицы и даст -2147483648.   -  person lurker    schedule 15.09.2013
comment
@RohitJain Нет, мне нужно сначала разобраться с этим !!!   -  person vikkyhacks    schedule 15.09.2013


Ответы (3)


В основном это происходит с целочисленным переполнением со знаком.

Проще взять byte в качестве примера. Значение byte всегда находится в диапазоне от -128 до 127 (включительно). Итак, если у вас есть значение 127 (которое равно 0x7f), если вы добавите 1, вы получите -128. Это также то, что вы получите, если приведете 128 (0x80) к byte:

int x = 0x80; // 128
byte y = (byte) x; // -128

Переполнение (в целочисленных представлениях с дополнением до 2) всегда идет от самого высокого выражаемого числа к самому низкому.

Для типов unsigned наибольшее значение переполняется до 0 (что опять же является наименьшим выражаемым числом). Это сложнее показать в Java, так как единственный беззнаковый тип — char:

char x = (char) 0xffff;
x++;
System.out.println((int) x); // 0
person Jon Skeet    schedule 15.09.2013
comment
На самом деле y равно -128. - person Seth; 25.02.2017
comment
@ghuizhang: Упс, исправлено. (Это было правильно даже в описательном тексте выше...) - person Jon Skeet; 25.02.2017

Это тот случай, когда происходит переполнение по отношению к диапазону типа данных. Вот пример, которым я могу поделиться.

int number = 0x80; // 0x80 is hexadecimal for 128 (decimal)
byte castedNumber = (byte)(number); // On casting, there is overflow,as byte ranges from -128 to 127 (inclusive).
System.out.println(castedNumber); //Output is -128.
person N. Pamnani    schedule 02.08.2016

Целочисленный диапазон для java: от -2 147 483 648 до 2 147 483 647. Задано шестнадцатеричное значение 0x80000000, его эквивалентное десятичное значение равно 2 147 483 648 (преобразование дополнения до 1). Вы можете видеть, что десятичное значение не помещается в диапазон, который называется целочисленным переполнением. Всякий раз, когда происходит переполнение, он обращается к другому концу в этом случае -2 147 483 648.

person Rishibalaji    schedule 08.03.2021