Что такое беззнаковые целые числа?

Ответ

Беззнаковые (unsigned) целые числа — это целочисленные типы данных, которые могут представлять только неотрицательные значения (от 0 до максимума для данного размера). Весь диапазон битов используется для хранения величины, что удваивает максимальное положительное значение по сравнению со знаковым (signed) типом того же размера.

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

Пример эмуляции 32-битного беззнакового int:

// int со значением -1 в знаковом представлении
int signedInt = 0xFFFFFFFF; // -1
// Преобразование в беззнаковое значение (хранится в long)
long unsignedLong = signedInt & 0xFFFFFFFFL; // 4294967295
System.out.println(unsignedLong);

Типичные операции:

  • Для byte: byteValue & 0xFF
  • Для short: shortValue & 0xFFFF
  • Для int: intValue & 0xFFFFFFFFL (результат в long)
  • С Java 8 появились методы-обёртки для беззнаковой арифметики (например, Integer.divideUnsigned()).

Ответ 18+ 🔞

А, беззнаковые числа, да? Ну это ж классика, блядь! Представь себе, что у тебя есть ящик для инструментов, но ты договорился с собой, что будешь хранить там только отвёртки. Никаких молотков, блядь, только отвёртки! Вот это и есть unsigned — туда только положительные циферки, от нуля и до упора. Весь ящик, все биты, блядь, работают на величину, а не на знак. Поэтому влезает в два раза больше, чем в знаковый такой же ящик.

А теперь смотри сюда, в Java-то прикол, ёпта! Тут примитивных беззнаковых типов — нихуя! Ну нет их, и всё тут. Как будто сказали: «А нехуй, сами как-нибудь». Но мы же не лыком шиты, мы эмулировать будем, через типы побольше да битовые операции.

Вот, смотри, как беззнаковый int изобразить, 32-битный:

// int со значением -1 в знаковом представлении
int signedInt = 0xFFFFFFFF; // -1
// Преобразование в беззнаковое значение (хранится в long)
long unsignedLong = signedInt & 0xFFFFFFFFL; // 4294967295
System.out.println(unsignedLong);

Видишь магию? Берем наш int, который в себе минус один держит, и делаем ему & (логическое И, блядь) с маской 0xFFFFFFFFL. Буква L в конце — это чтоб long получился, а то мало ли. И оп-па! Из минус единицы получается 4 миллиарда с хвостиком! Вот это я понимаю — фокус, в рот меня чих-пых!

И так со всеми, сука:

  • byte без знака — byteValue & 0xFF
  • short без знака — shortValue & 0xFFFF
  • int без знака — intValue & 0xFFFFFFFFL (и результат-то уже в long летит, ёбта!)

А с Java 8 вообще красота наступила, добавили в обёртки методы специальные, типа Integer.divideUnsigned(). Теперь можно делить, как будто числа беззнаковые, и не париться. Вообще охуенно, если честно. Раньше-то самим приходилось выкручиваться, а теперь — раз, и готово.