Тут є хороші відповіді, але я не бачу жодних демонстрацій бітових операцій. Як каже Visser (зараз прийнята відповідь), Java підписує цілі числа за замовчуванням (Java 8 має цілі числа без підпису, але я ніколи їх не використовував). Без зайвих прихильників, зробимо це ...
Приклад RFC 868
Що станеться, якщо вам потрібно записати не підписане ціле число в IO? Практичний приклад - коли потрібно вивести час відповідно до RFC 868 . Для цього потрібно 32-розрядне ціле число без великого ендіану, яке кодує кількість секунд з 00:00 1 січня 1900 р. Як би ви це кодували?
Зробіть власне 32-розрядне ціле число без підпису таким чином:
Оголосити масив байтів у 4 байти (32 біта)
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
Це ініціалізує масив, див. Чи байтовані масиви байтів ініціалізовані до нуля в Java? . Тепер вам потрібно заповнити кожен байт масиву інформацією в порядку великого ендіану (або малоекземлянина, якщо ви хочете зруйнувати хаос). Якщо припустити, що у вас тривалий час, що містить час (довгі цілі числа в Яві мають 64 біти), який називається secondsSince1900
(який використовує лише перші 32 біти, і ви обробили той факт, що посилання на дату 00:00 1 січня 1970 р.), То ви можете використовувати логічний AND, щоб витягти з нього біти і перемістити ці біти в позиції (цифри), які не будуть ігноровані, коли будете переведені в байт, і в порядку великого ендіану.
my32BitUnsignedInteger[0] = (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24); // first byte of array contains highest significant bits, then shift these extracted FF bits to first two positions in preparation for coersion to Byte (which only adopts the first 8 bits)
my32BitUnsignedInteger[1] = (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
my32BitUnsignedInteger[2] = (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
my32BitUnsignedInteger[3] = (byte) ((secondsSince1900 & 0x00000000000000FFL); // no shift needed
Наше my32BitUnsignedInteger
тепер еквівалентне непідписаному 32-бітовому цілому цілому цілому числу, яке відповідає стандарту RCF 868. Так, довгий тип даних підписаний, але ми проігнорували цей факт, оскільки ми припустили, що секунди Since1900 використовували лише нижні 32 біти). Через примушування довгих байтів, всі біти вище 2 ^ 7 (перші дві цифри в шістнадцятковій версії) будуть ігноруватися.
Посилання на джерело: Мережеве програмування Java, 4-е видання.