[Java/Tip] 자바에서 unsigned byte 다루기.

by Blogger 하얀쿠아
2012. 2. 2. 10:12 소프트웨어 Note/Java
자바의 Primitive Data Type 들 중에는 unsigned 데이터 타입이 존재하지 않습니다.

unsigned를 특별히 사용할 일이 없을때는 의식하지 못하고 있었는데, 자바에서(정확히는 안드로이드에서 사용할 목적으로) 음성을 G.711 인코딩/디코딩 하기 위한 코덱을 구현 하던 중 깨닫게 되었습니다.

byte 타입을 unsigned 로 0~255 을 사용하고 싶었지만, 자바에서는 unsigned 키워드 자체가 존재하지 않아 byte 타입은 -128~127 의 값을 갖게 되어 있더군요. 즉 2's complement 의 값입니다.

하지만 제가 필요한 것은 0~255 의 범위값이었습니다. 
정확히는, C#에서 byte 타입으로 보낸 0~255의 값 (이진 값으로는 0000 0000 ~ 1111 1111 이 되겠죠) 을 자바에서도 0~255로 해석하도록 해야 했습니다.

그래서 이를 해결하기 위해 꼼수를 생각해 본 결과..

다음과 같이 하여 해결 할 수 있었습니다. 

byte value = xxx;
int nValue = 0;

if (value < 0)
 nValue = (int)value + 256;
else
 nValue = (int)value;

결과적으로 nValue에는 byte 값을 unsigned 로 변환한 값이 들어가게 됩니다.
원리는 간단하죠. 
0~127 값은 그대로 사용하면 됩니다. 2진수로 표현할 경우 0XXX XXXX 가 되기 때문이죠.
문제가 되는 -128~-1  은 2진수로 표현할 경우 1XXX XXXX 가 되며, MSB(most significant bit) 가 1이어서 어떻게 해석하느냐에 따라 표현되는 값이 달라지게 됩니다.  즉 unsigned 면 이를 128~255 로 표현 하겠죠. signed 면 2's complement 부호비트로 해석하여 -128 ~ -1 로 해석하는 것이죠.

결론은 -128 ~ -1 에 256을 더해주면, 됩니다.


 
이 댓글을 비밀 댓글로
    • 진짜궁금해서물어봄
    • 2019.02.21 21:08
    그냥 처음부터 byte에 128을 더하면 되지않나요??
      • ^^
      • 2019.02.27 15:06
      그러면 0~127을 표현할 수가 없지요~

      if를 사용하지 않고 싶다면
      int nValue = (int)value & 0xff 를 하시면 됩니다.

      1000 0000 인 byte 값을 int로 변환하면
      1111 1111 1111 1111 1111 1111 1000 0000 이 되고, 여기에
      0000 0000 0000 0000 0000 0000 1111 1111 을 and 연산해주면
      0000 0000 0000 0000 0000 0000 1000 0000 이 되어 -128이 아닌 128이 됩니다.

      자바의 거지같은 점이죠..ㅠㅠ
    • 박형준
    • 2019.06.11 12:10
    다른환경에서 암호화된 문자열 복호화 하는 과정에서 이 문제가 의심되서 검색해봤는데, 이런꿀팁이 있었다니 ㅜㅜ
    잘보고 갑니다