program tip

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

radiobox 2020. 9. 13. 10:19
반응형

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)호출은 정수의 char 표현, 즉 char로 변환됩니다 '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. useful for handling binary data formats (e.g. flat message formats, etc.)


Handling bytes and unsigned integers with 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

Except char, every other numerical data type in Java are signed.

As said in a previous answer, you can get the unsigned value by performing an and operation with 0xFF. In this answer, I'm going to explain how it happens.

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

If your machine is 32-bit, then the int data type needs 32-bits to store values. byte needs only 8-bits.

The int variable i is represented in the memory as follows (as a 32-bit integer).

0{24}11101010

Then the byte variable b is represented as:

11101010

As bytes are unsigned, this value represent -22. (Search for 2's complement to learn more on how to represent negative integers in memory)

Then if you cast is to int it will still be -22 because casting preserves the sign of a number.

1{24}11101010

The the casted 32-bit value of b perform and operation with 0xFF.

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

Then you get 234 as the answer.


If you want to use the primitive wrapper classes, this will work, but all java types are signed by default.

public static void main(String[] args) {
    Integer i=5;
    Byte b = Byte.valueOf(i+""); //converts i to String and calls Byte.valueOf()
    System.out.println(b);
    System.out.println(Integer.valueOf(b));
}

in java 7

public class Main {
    public static void main(String[] args) {
        byte b =  -2;
        int i = 0 ;
        i = ( b & 0b1111_1111 ) ;
        System.err.println(i);
    }
}

result : 254

참고URL : https://stackoverflow.com/questions/7401550/how-to-convert-int-to-unsigned-byte-and-back

반응형