[java] Java로 부호없는 바이트를 만들 수 있습니까?

부호없는 바이트를 부호없는 바이트로 변환하려고합니다. 문제는 내가받는 데이터가 서명되지 않았고 Java가 부호없는 바이트를 지원하지 않기 때문에 데이터를 읽을 때 부호있는 것으로 취급합니다.

Stack Overflow에서 얻은 다음 솔루션으로 변환하려고했습니다.

public static int unsignedToBytes(byte a)
{
    int b = a & 0xFF;
    return b;
}

그러나 다시 바이트로 변환되면 동일한 부호있는 데이터가 표시됩니다. 이 데이터를 매개 변수로 바이트 만 허용하는 Java 함수의 매개 변수로 사용하려고하므로 다른 데이터 형식을 사용할 수 없습니다. 이 문제를 어떻게 해결할 수 있습니까?



답변

귀하의 질문을 이해하지 못했습니다.

방금 이것을 시도하고 바이트 -12 (서명 값)에 대해 정수 244 (부호없는 바이트 값과 동일하지만으로 입력)를 반환했습니다 int.

  public static int unsignedToBytes(byte b) {
    return b & 0xFF;
  }

  public static void main(String[] args) {
    System.out.println(unsignedToBytes((byte) -12));
  }

당신이하고 싶은 일입니까?

자바는 같은 244 표현할 수 없습니다 byte겠습니까 C.에 위에서 양의 정수 표현으로, 값이 Byte.MAX_VALUE(127)는 같은 타 정수 유형을 사용해야합니다 short, int또는 long.


답변

프리미티브가 Java로 서명되었다는 사실은 메모리 / 전송에서 표현되는 방식과 관련이 없습니다. 바이트는 8 비트에 불과하며 서명 된 범위로 해석하는지 여부는 귀하에게 달려 있습니다. “this is signed”또는 “this is unsigned”라고 말하는 마술 깃발은 없습니다.

프리미티브가 서명되면 Java 컴파일러는 +127보다 높은 값을 바이트 (또는 -128보다 작은)에 할당하지 못하게합니다. 그러나 이것을 달성하기 위해 int (또는 short)를 다운 캐스팅하는 것을 막을 수는 없습니다.

int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)

/*
 * Will print a negative int -56 because upcasting byte to int does
 * so called "sign extension" which yields those bits:
 * 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
 *
 * But you could still choose to interpret this as +200.
 */
System.out.println(b); // "-56"

/*
 * Will print a positive int 200 because bitwise AND with 0xFF will
 * zero all the 24 most significant bits that:
 * a) were added during upcasting to int which took place silently
 *    just before evaluating the bitwise AND operator.
 *    So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
 * b) were set to 1s because of "sign extension" during the upcasting
 *
 * 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
 * &
 * 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
 * =======================================
 * 0000 0000 0000 0000 0000 0000 1100 1000 (200)
 */
System.out.println(b & 0xFF); // "200"

/*
 * You would typically do this *within* the method that expected an
 * unsigned byte and the advantage is you apply `0xFF` only once
 * and than you use the `unsignedByte` variable in all your bitwise
 * operations.
 *
 * You could use any integer type longer than `byte` for the `unsignedByte` variable,
 * i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
 * it would get casted to `int` anyway.
 */
void printUnsignedByte(byte b) {
    int unsignedByte = b & 0xFF;
    System.out.println(unsignedByte); // "200"
}


답변

Java에서 부호없는 바이트로 작업하기위한 전체 안내서 :

Java에서 부호없는 바이트

(이 답변의 출처.)


Java 언어는 unsigned키워드 와 같은 것을 제공하지 않습니다 . byte언어 사양에 따른 -128 사이의 값을 나타냅니다 – 예를 들어 127, A는 경우 byte에 캐스팅 int부호 및 사용과 같은 첫 번째 비트 해석합니다 자바 부호 확장을 .

즉, byte단순히 8 비트로 볼 수 없으며 그 비트를 0에서 255 사이의 값으로 해석 할 수 없습니다. 다른 사람의 방법에 대해 해석을 강요하기 위해 할 수있는 것은 없습니다. 메소드가 a를 승인하면 byte, 달리 명시되지 않는 한 해당 메소드는 -128에서 127 사이의 값을 승인합니다.

다음은 사용자 편의를위한 유용한 변환 / 조작 몇 가지입니다.

int로 /에서 변환

// From int to unsigned byte
int i = 200;                    // some value between 0 and 255
byte b = (byte) i;              // 8 bits representing that value

// From unsigned byte to int
byte b = 123;                   // 8 bits representing a value between 0 and 255
int i = b & 0xFF;               // an int representing the same value

또는 Java 8 이상인 경우을 사용하십시오 Byte.toUnsignedInt.

파싱 ​​/ 포맷

가장 좋은 방법은 위의 전환을 사용하는 것입니다.

// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");

// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));

산술

2의 보수 표현은 덧셈, 뺄셈 및 곱셈에 대해 “그냥 작동합니다”:

// two unsigned bytes
byte b1 = (byte) 200;
byte b2 = (byte) 15;

byte sum  = (byte) (b1 + b2);  // 215
byte diff = (byte) (b1 - b2);  // 185
byte prod = (byte) (b2 * b2);  // 225

Division은 피연산자를 수동으로 변환해야합니다.

byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));


답변

Java에는 원시 부호없는 바이트가 없습니다. 일반적인 것은 더 큰 유형으로 캐스팅하는 것입니다.

int anUnsignedByte = (int) aSignedByte & 0xff;


답변

다른 답변은 메모리 표현을 다루고 있으며 메모리 처리 방법은 사용 계획에 따라 다릅니다. Java 8이 unsigned types 처리에 대한 지원을 추가했다고 덧붙일 것입니다 . 이 경우에는Byte.toUnsignedInt

int unsignedInt = Byte.toUnsignedInt(myByte);


답변

참고로, 인쇄하고 싶다면

byte b = 255;
System.out.println((b < 0 ? 256 + b : b));


답변

당신이 이런 것을 찾고 있다고 생각한다면.

public static char toUnsigned(byte b) {
    return (char) (b >= 0 ? b : 256 + b);
}