Использование Unsigned int (примитив) и Integer (объект) в Java

Я следую учебнику Java по примитивным типам данных. В начале говорится, что

В Java SE 8 и более поздних версиях можно использовать тип данных int для представления 32-разрядного целого числа без знака, минимальное значение которого равно 0, а максимальное — 2^32-1. Используйте класс Integer, чтобы использовать тип данных int как целое число без знака.

Из этой цитаты я понимаю, что теперь я могу хранить до 2 ^ 32-1 как int, если я использую объект-оболочку Integer, а не примитивный тип данных int. Но когда я попробовал это, мой компилятор жалуется, что значение, которое я использую, слишком велико, 2 ^ 31. Я пробовал это, используя как примитивный тип данных, так и Object.

Integer integerObjectLarge = 2147483648; //2^31
int integerPrimitiveLarge = 2147483648; //2^31

Как именно я могу использовать int/Integer для хранения значения без знака, например 2 ^ 31?


person Pasaribu    schedule 25.07.2014    source источник


Ответы (3)


Но когда я попробовал это, мой компилятор жалуется, что значение, которое я использую, слишком велико, 2 ^ 31.

Произошла ошибка, поскольку литерал 2147483648 синтаксически неверен.


Как именно я могу использовать int/Integer для хранения значения без знака, например 2 ^ 31?

Вы по-прежнему можете выполнять арифметические операции без знака, используя новые методы Integer , просто не используйте недопустимые литералы:

int n = 2147483647 + 1;  // 2^31

System.out.println(Integer.toUnsignedString(n));  // treat int as unsigned
System.out.println(Integer.toString(n));          // treat int as signed
2147483648
-2147483648

Из этой цитаты я понимаю, что теперь я могу хранить до 2 ^ 32-1 как int, если я использую объект-оболочку Integer, а не примитивный тип данных int.

Вы можете сохранить целое число без знака, используя примитивный тип int, но использование значения в качестве типа без знака требует использования служебных методов Integer, как показано выше.

person arshajii    schedule 25.07.2014

Я не думаю, что Java добавила true беззнаковый 32-битный тип int. Единственное, что изменилось, это то, что класс Integer теперь содержит некоторые методы, которые будут обрабатывать 32-разрядное целое число (целые числа) как 32-разрядное целое число без знака. См. compareUnsigned, divideUnsigned, parseUnsignedInt и некоторые другие в javadoc для Integer. Long также имеет несколько новых методов.

Но в основном, если вы храните битовый шаблон (например) 10001000_11110000_10010110_11000010 в int, в int нет ничего, что говорило бы «Это целое число без знака» или «Это целое число со знаком». Это зависит от того, какие методы вы используете для работы с ним.

person ajb    schedule 25.07.2014
comment
Да, разработчики языка Java продолжают свою традицию запутывания, а не разъяснения. - person Hot Licks; 26.07.2014
comment
Я могу понять, почему они могли не захотеть добавлять новый примитивный тип. Но мне пришло в голову, что они могли бы добавить новый буквенный суффикс, не делая ничего обратно несовместимым или изменяя какие-либо другие языковые правила, так что, скажем, 2147483649U будет эквивалентно int -2147483647. - person ajb; 26.07.2014
comment
Да, можно было бы добавить суффикс (хотя это может потребовать незначительных изменений JVM). И я полагаю, что если вы используете L, вам понадобится приведение, чтобы компилятор не возражал. - person Hot Licks; 26.07.2014

Вы всегда могли хранить целочисленные литералы без знака, используя шестнадцатеричный код:

 int x = 0xffffffff;
 // or any value >= 0x80000000;

Это связано с тем, что для всех практических целей компилятор считает их «подписанными».

Вы по-прежнему не можете присвоить десятичное значение > 2 ^ 31 - 1, потому что это создало бы всевозможные проблемы с обратной совместимостью, если бы это было внезапно разрешено.

person Lin Sherman    schedule 25.07.2014