Рубрики
Без рубрики

Java – Преобразование байтов в байты без знака

В Java нет байтов без знака (от 0 до 255). Чтобы создать байт без знака, мы можем преобразовать байт в int и замаскировать (побитово и) новый inn с помощью 0xff, чтобы получить последние 8 битов или предотвратить расширение знака.

В Java байт – это 8-разрядный подписанный (положительный и отрицательный) тип данных, значения из -128 (-2^7) к 127 (2^7-1) . Для байта без знака , допустимые значения от 0 чтобы 255 .

В Java нет байтов без знака (от 0 до 255). Чтобы создать байт без знака, мы можем преобразовать байт в int и замаскировать (побитово и) новый inn с помощью 0xff , чтобы получить последние 8 битов или предотвратить расширение знака.

  byte aByte = -1;
  int number = aByte & 0xff;  // bytes to unsigned byte in an integer.

Зачем приводить байт к int? Java использует дополнение два для представления чисел со знаком (положительных и отрицательных), крайний левый бит обозначает знак (0 положительный, 1 отрицательный), остальные биты представляют значения из -128 (-2^7) до 127 (2^7-1) , так называемый 8-разрядный байт имеет только 7 бит для хранения значений. Дополнительные значения (128 – 255) не могут поместиться в один байт , и мы приводим его к 32-разрядному целому числу без знака для большего количества пробелов (битов).

Предпосылка

1. Байты в байт без знака

1.1 Просмотрите следующую таблицу для преобразования байт в байт без знака (int) :

1 1
2 2
127 127
-128 128
-127 129
-126 130
-2 254
-1 255

1.2 Сначала мы преобразуем байт 8-разрядный в int 32-разрядный.

Например, байт-1 в дополнении к двум двоичный файл равен 1111 1111 .

# two's complement formula to convert positive to negative
# leftmost bit, 1 is negative, 0 is positive

0000 0001 (1)
1111 1110 (invert bits)
1111 1111 (add 1)
1111 1111 (-1)

Когда мы преобразуем или передаем байт в int , это увеличит биты с 8 до 32. Расширение знака будет применено и заполнит значения увеличенных битов.

1111 1111 (-1)

byte -> int
???? ???? | ???? ???? | ???? ???? | 1111 1111

sign extension
1111 1111 | 1111 1111 | 1111 1111 | 1111 1111

1.3 Теперь мы выполняем побитовое и или & с помощью 0xff , чтобы получить последние 8 битов.

1111 1111 | 1111 1111 | 1111 1111 | 1111 1111  (int -1)
&
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111  (0xff)
=
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111  (last 8 bits)

1.4 Двоично-десятичное вычисление.

1  1  1  1  1   1   1    1
1, 2, 4, 8, 16, 32, 64, 128 = 255

Сделано. Для -1 теперь у нас 255.

  byte aByte = -1;
  int number = aByte & 0xff;
  System.out.println(number);  // output = 255

2. Java 8

В Java 8 появилось много новых API-интерфейсов для поддержки операций без знака, например байт , теперь у нас есть Байт.toUnsignedInt() для преобразования байта со знаком в целое число без знака.

package com.mkyong.crypto.bytes;

public class Java8UnsignedByte {

    public static void main(String[] args) {

        byte aByte = (byte) -2;                              // -2 (signed) and 254 (unsigned)
        System.out.println(aByte);                           // -2

        // Java 8
        System.out.println(Byte.toUnsignedInt(aByte));       // 254

    }
}

Просмотрите новый Байт.Подписанный ; Java 8 использует ту же технику для преобразования байта в целое число без знака.

public final class Byte extends Number implements Comparable {

  /*
  @since 1.8
  */
  public static int toUnsignedInt(byte x) {
        return ((int) x) & 0xff;
  }

3. Старая Java + Комментарии

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

package com.mkyong.crypto.bytes;

public class JavaUnsignedByte {

    public static void main(String[] args) {

        byte input = (byte) -2;                         // -2 (signed) and 254 (unsigned)

        // -2 = 1111 1110 , two's complement
        System.out.println("Input : " + input);

        // byte (8 bits) cast / widen to int (4 bytes, 16 bits), sign extension will apply
        // 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
        int input2 = (int) input;

        System.out.println("Input [Binary] : " + Integer.toBinaryString(input2));

        // 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
        // &
        // 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (0xFF) , get last 8 bits
        // =============================================
        // 0000 0000 | 0000 0000 | 0000 0000 | 1111 1110  unsigned int
        int result = input2 & 0xff;

        System.out.println(result); // 254
        System.out.println(Integer.toBinaryString(result)); // 1111 1110

    }
}

Рекомендации

Оригинал: “https://mkyong.com/java/java-convert-bytes-to-unsigned-bytes/”