sm2tc.

이 함수는 tc2sm의 역함수(?)입니다.

MSB에 sign과 나머지 절대값으로 표현된 값을 2의 보수로 바꾸는 문제입니다.

 

방법은 tc2sm함수와 비슷합니다.

sign bit가 0이면 그대로 반환하고 1이면 2의 보수를 취합니다.

 

여기서 쓴 기법이 이것입니다.

(x | (x >> 31))

위와 같은 코드를 쓰면 sign bit가 0인 경우 x가 나오지만,

sign bit가 1인 경우 0xffffffff가 나옵니다.

그리고 뒤에 코드인 (~(x >> 31) | (~(x + (1 << 31)) + 1))은

sign bit가 0인 경우 0xffffffff가 나오고,

sign bit가 1인 경우 뒤의 2의 보수를 취한 결과가 나옵니다.

따라서 최종적으로 sign bit가 0인 경우 x에 0xffffffff를 AND 연산하여 x를 내놓지만,

sign bit가 1인 경우 0xffffffff에 2의 보수를 AND 연산하니 2의 보수가 나옵니다.

if문을 쓰지 않아도 되더군요.^^

 

사실 이 함수에서 저와 같은 기법을 발견하였습니다.

그래서 다른 함수에서 저와 유사한 기법으로 if문을 써야 할 곳을 처리하였습니다.

 

 

/*
* sm2tc - Convert from sign-magnitude to two's complement
*   where the MSB is the sign bit
*   Example: sm2tc(0x80000005) = -5.
*   Legal ops: ! ~ & ^ | + << >>
*   Max ops: 15
*   Rating: 4
*/
int sm2tc(int x) {
    /* It's same tc2sm except x is negative.
     * if x is negative(it means sign bit is 1),
     * remove sign bit(sign bit = 0), and ~x + 1(+ -> - two's complement)
     *
     * if MSB 0 then x -> x
     * if MSB 1 then x -> ~(x + 0x80000000) + 1
     *
     * if MSB 0 then x >> 31 == 0x00000000
     * (x | (x >> 31)) == x
     * and ~(x >> 31) == 0xffffffff, So x & 0xffffffff == x
     * return x
     *
     * if MSB 1 then x >> 31 == 0xffffffff
     * (x | (x >> 31)) == 0xffffffff
     * and ~(x >> 31) == 0x00000000, So (~(x >> 31) | (~(x + (1 << 31)) + 1)) == ~(x + 0x80000000) + 1.
     * finally return two's complement
     *
     * 20080403
     */
    return (x | (x >> 31)) & (~(x >> 31) | (~(x + (1 << 31)) + 1));
}

크리에이티브 커먼즈 라이선스
Creative Commons License

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/1488

댓글을 달아 주세요

[로그인][오픈아이디란?]