2013-02-04 3 views
1

Java에서 값을 결정하는 데 필요한 3 바이트 부호있는 숫자가 있습니다. 나는 그것이 하나의 보완으로 서명된다고 믿지만 나는 100 % 확신하지 못한다. (나는이 문제를 10 년 이상 공부하지 않고 내 문제의 문서는 분명하지 않다.) Java가 모든 문제를 2의 보수로 처리한다고 생각합니다. I는 표시하는 구체적인 예를 가지고Java에서 부호있는 숫자 및 보완 문자 이해

  • 원래 3 바이트 번호 : 정수로서 해석 0xEE1B17

  • (Integer.parseInt(s, 16))은이된다 : 15,604,503

  • I 간단한 비트 않으면 플립 (~)이 2의 보충 표현을 얻을 수 있다고 생각합니다. -15604504

  • 하지만 내가 얻고있는 값은 다음과 같습니다. -1172713

나는 int의 3 바이트가 아니라 전체 int의 2의 보수를 얻고 있습니다.하지만이 문제를 해결하는 방법을 모르겠습니다.

내가 할 수 있었던 것은 정수를 이진 문자열 (Integer.toBinaryString())로 변환 한 다음 수동으로 모든 0을 1로 반전하고 그 반대의 경우도 마찬가지입니다. 그 다음이 정수 (Integer.parseInt(s, 16))를 파싱하면 1172712가 매우 가깝습니다. 다른 모든 예에서 나는 결과에 항상 1을 더하여 해답을 얻을 필요가있다.

여기에서 어떤 유형의 부호있는 숫자 인코딩이 사용되고 있는지 진단 할 수 있으며 문자열의 모든 문자를 수동으로 뒤집는 것 이외의 해결책이 있습니까? 이 일을 훨씬 더 우아한 방법으로 생각해야합니다.

EDIT : 모든 응답자가 여러 가지 방법으로 도움을주었습니다. 그러나 일반적인 질문은 3 바이트 숫자를 뒤집고 @ louis-wasserman이이 질문에 대답하고 가장 먼저 대답하여 해결 방법으로 표시하는 것입니다. 도움을 주신 모든 분들께 감사드립니다!

답변

2

Java int의 하위 3 바이트를 뒤집으려면 ^ 0x00FFFFFF을 사용하십시오.

+0

예, 감사합니다. 간단 할 것입니다. 당신의 대답은 내가 찾고 있었기 때문에 해결책으로 표시 하겠지만 원하는 결과를 얻으려면 그 번호에 1을 추가해야하는 이유는 무엇입니까? – rjcarr

+0

2의 보수로'~ x == -x - 1'입니다. 아마 이것은 보완 물의 유물 일 것입니다. –

1

0xFFEE1B17은 - 1172713 앞에 오는 바이트 만 추가해야합니다. FF은 3 바이트 값의 최상위 비트가 설정되고 그렇지 않으면 00입니다.

과 같이 할 수있는 적절한 int에 3 바이트 값을 변환하는 방법

if(byte3val>7FFFFF) 
    return byte3val| 0xFF000000; 
else 
    return byte3val; 
+0

빠른 응답을 주셔서 감사합니다 ... "0xFFEE1B17이 -1172713"이라고 말할 때 어떤 숫자의 보수를 의미합니까? – rjcarr

+0

@rjcarr : 거의 모든 시스템에서 (또한 Java로도) [2-compliment] (http://en.wikipedia.org/wiki/Two's_complement) – MrSmith42

0

부정적인 서명 숫자가 정의되어 a + (-a) = 0 있도록. 따라서 모든 비트가 뒤집힌 다음 1이 추가되었음을 의미합니다. Two's complement을 참조하십시오. a + ~a + 1을 추가 할 때 어떤 일이 발생하는지 생각함으로써이 프로세스가 조건을 만족하는지 확인할 수 있습니다.

숫자가 가장 중요한 비트만큼 음수라는 것을 알 수 있습니다.그래서 당신은 4 바이트의 수에 서명 3 바이트 수를 변환해야하는 경우, 당신은 비트를 확인하여 그것을 할 수 있으며이 설정되어있는 경우, 또한 네 번째 바이트의 비트 설정 :

if ((a & 0x800000) != 0) 
    a = a | 0xff000000; 

당신은 할 수 있습니다

a = (0xfffffe << a) >> a; 
다음

<<>> 바이트를 수행 더 (분기 현재의 CPU에 pipelining 잘 재생되지 않습니다) 계산에 분기가 없기 때문에, 가장 가능성이 더 잘 수행하는 하나의 표현, 또한 그것을 할 교대. 먼저 숫자 8 비트를 오른쪽으로 이동합니다 (이제는 3 개의 "낮은"바이트 대신 3 개의 "상위"바이트를 차지합니다). 그런 다음 다시 이동하십시오. 트릭은 >>Arithmetic shift이라고도하며 부호있는 시프트이라고도합니다. 연산에 의해 비어있는 모든 비트에 최상위 비트를 복사합니다. 이것은 정확히 숫자의 부호를 유지하는 것입니다. 실제로 :

(0x1ffffe << 8) >> 8  -> 2097150 
(0xfffffe << 8) >> 8  -> -2 

Java에는 부호없는 오른쪽 시프트 연산자 >>>이 있습니다. 자세한 내용은 Java 자습서 : Bitwise and Bit Shift Operators을 참조하십시오.

+0

@ MrSmith42를 사용했습니다. 지적 해 주셔서 감사합니다. 그것을 바로 잡았다. 물론 비트와/또는 비트이어야합니다. –