[java] Int를 부호없는 바이트로 변환하고 그 반대로 변환하는 방법

숫자를 부호없는 바이트로 변환해야합니다. 숫자는 항상 255보다 작거나 같으므로 1 바이트에 맞습니다.

또한 해당 바이트를 해당 숫자로 다시 변환해야합니다. Java에서 어떻게 할 수 있습니까? 나는 여러 가지 방법을 시도했지만 아무것도 작동하지 않습니다. 지금 내가하려는 작업은 다음과 같습니다.

int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);

이제 해당 바이트를 다시 숫자로 변환합니다.

Byte test = new Byte(binaryByte);
int msgSize = test.intValue();

분명히 이것은 작동하지 않습니다. 어떤 이유로 항상 숫자를 65. 어떤 제안?



답변

바이트는 항상 Java로 서명됩니다. 그러나 0xFF로 이진화하여 부호없는 값을 얻을 수 있습니다.

int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234


답변

Java 8은 서명되지 않은 변환 Byte.toUnsignedInt으로 변환 byte을 제공 합니다 int. Oracle의 JDK에서는 return ((int) x) & 0xff;HotSpot이 이미이 패턴을 최적화하는 방법을 이해하고 있지만 다른 VM에 내장 될 수 있기 때문에 간단히 구현됩니다 . 더 중요한 것은 호출이 무엇을하는지 이해하기 위해 사전 지식이 필요하지 않다는 것 toUnsignedInt(foo)입니다.

총, 자바 8 변환하는 방법을 제공 byte하고 short서명을 int하고 long, 그리고 int부호로를 long. 변환하는 방법은 byte서명을가 short하였다 고의로 생략 JVM이 단지 산술 제공하므로 intlong어쨌든.

int를 다시 바이트로 변환하려면 캐스트를 사용하십시오 : (byte)someInt. 결과적으로 축소되는 기본 변환 은 마지막 8 비트를 제외한 모든 비트를 버립니다.


답변

예상되는 8 비트 값을 부호있는 정수에서 부호없는 값으로 변환해야하는 경우 간단한 비트 이동을 사용할 수 있습니다.

int signed = -119;  // 11111111 11111111 11111111 10001001

/**
 * Use unsigned right shift operator to drop unset bits in positions 8-31
 */
int psuedoUnsigned = (signed << 24) >>> 24;  // 00000000 00000000 00000000 10001001 -> 137 base 10

/**
 * Convert back to signed by using the sign-extension properties of the right shift operator
 */
int backToSigned = (psuedoUnsigned << 24) >> 24; // back to original bit pattern

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

int기본 유형 이 아닌 다른 것을 사용하는 경우 분명히 이동량을 조정해야합니다. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

또한 bytetype을 사용할 수 없으므로 다른 응답자가 언급 한대로 부호있는 값이 생성됩니다. 8 비트 부호없는 값을 나타내는 데 사용할 수있는 가장 작은 기본 유형은 short.


답변

Integer.toString(size)하여 정수의 문자 표현으로 통화 변환은 문자를 즉 '5'. 해당 문자 의 ASCII 표현 은 값 65입니다.

Integer.parseInt원래 int 값을 되돌리려면 먼저를 사용하여 문자열을 정수 값으로 다시 구문 분석해야 합니다.

결론적으로, 부호있는 / 부호없는 변환 String의 경우 @JB가 제안하는대로 그림에서 벗어나 비트 조작을 사용 하는 것이 가장 좋습니다.


답변

솔루션은 잘 작동하지만 (감사합니다!) 캐스팅을 피하고 저수준 작업을 JDK에 남겨두고 싶다면 DataOutputStream을 사용하여 int를 작성하고 DataInputStream을 사용하여 다시 읽을 수 있습니다. 자동으로 unsigned로 처리됩니다. 바이트 :

int를 바이너리 바이트로 변환하기 위해;

ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
int val = 250;
dos.write(byteVal);
...
dos.flush();

다시 읽기 :

// important to use a (non-Unicode!) encoding like US_ASCII or ISO-8859-1,
// i.e., one that uses one byte per character
ByteArrayInputStream bis = new ByteArrayInputStream(
   bos.toString("ISO-8859-1").getBytes("ISO-8859-1"));
DataInputStream dis = new DataInputStream(bis);
int byteVal = dis.readUnsignedByte();

Esp. 바이너리 데이터 형식 (예 : 플랫 메시지 형식 등)을 처리하는 데 유용합니다.


답변

를 제외하고 charJava의 다른 모든 숫자 데이터 유형은 서명됩니다.

이전 답변에서 말했듯이을 사용하여 and작업을 수행하여 부호없는 값을 얻을 수 있습니다 0xFF. 이 답변에서 어떻게 발생하는지 설명하겠습니다.

int i = 234;
byte b = (byte) i;
System.out.println(b);  // -22

int i2 = b & 0xFF;
// This is like casting b to int and perform and operation with 0xFF

System.out.println(i2); // 234

머신이 32 비트 인 경우 int데이터 유형에 값을 저장하려면 32 비트가 필요합니다. byte8 비트 만 필요합니다.

int변수는 i(32 비트 정수로서) 다음 메모리에 표시된다.

0{24}11101010

그런 다음 byte변수 b는 다음과 같이 표시됩니다.

11101010

으로 byte의가 서명되지 않은 경우,이 값은 나타냅니다 -22. (메모리에서 음의 정수를 표현하는 방법에 대해 자세히 알아 보려면 2의 보수를 검색하십시오)

그런 다음 캐스팅하면 캐스팅이 숫자의 부호를 유지하기 때문에 int여전히 될 것 -22입니다.

1{24}11101010

으로 작업 수행 의 캐스트 된 32-bit값입니다 .band0xFF

 1{24}11101010 & 0{24}11111111
=0{24}11101010

그럼 당신 234은 답 을 얻습니다 .


답변

BigInteger로 바이트와 부호없는 정수 처리 :

byte[] b = ...                    // your integer in big-endian
BigInteger ui = new BigInteger(b) // let BigInteger do the work
int i = ui.intValue()             // unsigned value assigned to i