Объявление неподписанного int в Java - PullRequest
277 голосов
/ 24 марта 2012

Есть ли способ объявить целое без знака в Java?

Или вопрос также может быть сформулирован так: каков эквивалент Java без знака?чтобы рассказать вам контекст, который я смотрел на реализацию Java String.hashcode().Я хотел проверить возможность столкновения, если целое число было 32 без знака int.

Ответы [ 10 ]

271 голосов
/ 24 марта 2012

В Java нет типа данных для целых чисел без знака .

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

Вы также можете использовать целое число со знаком, как если бы оно было без знака. Преимущество представления дополнения до двух состоит в том, что большинство операций (таких как сложение, вычитание, умножение и сдвиг влево) идентичны на двоичном уровне для целых чисел со знаком и без знака. Однако некоторые операции (деление, сдвиг вправо, сравнение и приведение) отличаются. Начиная с Java SE 8, новые методы в классе Integer позволяют полностью использовать тип данных int для выполнения арифметики без знака :

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

Обратите внимание, что int переменные по-прежнему подписаны при объявлении, но теперь возможна арифметика без знака с использованием этих методов в классе Integer.

65 голосов
/ 25 ноября 2013
60 голосов
/ 08 апреля 2014

То, является ли значение в int знаком или без знака, зависит от того, как интерпретируются биты - Java интерпретирует биты как значение со знаком (у него нет беззнаковых примитивов).

Если у вас есть int, который вы хотите интерпретировать как значение без знака (например, вы читаете int из DataInputStream, который, как вы знаете, содержит значение без знака), то вы можете выполнить следующий трюк.

int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffl;

Обратите внимание, что важно, чтобы шестнадцатеричный литерал был длинным литералом, а не целым литералом - отсюда и буква 'l' в конце.

18 голосов
/ 06 августа 2014

Нам потребовались числа без знака для моделирования в MySQL без знака TINYINT, SMALLINT, INT, BIGINT в jOOQ , поэтому мы создали jOOU , a минималистичная библиотека, предлагающая типы обёрток для целых чисел без знака в Java. Пример:

import static org.joou.Unsigned.*;

// and then...
UByte    b = ubyte(1);
UShort   s = ushort(1);
UInteger i = uint(1);
ULong    l = ulong(1);

Все эти типы распространяются на java.lang.Number и могут быть преобразованы в примитивные типы высшего порядка и BigInteger. Надеюсь, это поможет.

(Отказ от ответственности: я работаю в компании за этими библиотеками)

7 голосов
/ 06 августа 2014

Для чисел без знака вы можете использовать эти классы из библиотеки Гуавы :

Они поддерживают различные операции:

  • плюс
  • минус
  • раз
  • mod
  • splitBy

В данный момент, похоже, не хватает операторов сдвига байтов.Если вам это нужно, вы можете использовать BigInteger из Java.

4 голосов
/ 02 декабря 2016

Используйте char для 16-битных целых чисел без знака.

1 голос
/ 09 октября 2018

Кажется, что вы можете решить проблему с подписью, выполнив «логическое И» для значений перед их использованием:

Пример (значение byte[] header[0] равно 0x86):

System.out.println("Integer "+(int)header[0]+" = "+((int)header[0]&0xff));

Результат:

Integer -122 = 134
1 голос
/ 30 июня 2017

Только что сделал этот кусок кода, который конвертирует this.altura из отрицательного числа в положительное.Надеюсь, это поможет кому-то нуждающемуся

       if(this.altura < 0){    

                        String aux = Integer.toString(this.altura);
                        char aux2[] = aux.toCharArray();
                        aux = "";
                        for(int con = 1; con < aux2.length; con++){
                            aux += aux2[con];
                        }
                        this.altura = Integer.parseInt(aux);
                        System.out.println("New Value: " + this.altura);
                    }
1 голос
/ 12 января 2016

Возможно, это то, что вы имели в виду?

long getUnsigned(int signed) {
    return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
  • getUnsigned(0) → 0
  • getUnsigned(1) → 1
  • getUnsigned(Integer.MAX_VALUE) → 2147483647
  • getUnsigned(Integer.MIN_VALUE) → 2147483648
  • getUnsigned(Integer.MIN_VALUE + 1) → 2147483649
0 голосов
/ 29 марта 2013

Вы можете использовать функцию Math.abs (число). Возвращает положительное число.

...