2017-10-05 15 views
1

저는 C 언어를 처음 사용하고 비트 조작으로 연습하고 있습니다.부호는 n 비트로 시작하는 32 비트로 확장됩니다. - C

n> 0 및 n < 31과 같은 n 비트 2의 보수가 있다고 가정합니다. n의 크기를 미리 알고있는 경우 어떻게 32 비트로 확장 할 수 있습니까? n은 가정 16 비트

int32_t extendMe(int16_t n) { 
    return (int32_t) n; 
} 

였다면

I 데이터 정의를 가진다.

서명하려는 n 비트 값이 32로 확장된다고 가정하면 어떻게해야합니까?

감사합니다.

+0

컴파일러에서 사용하는 음수 표현에 관계없이 2의 보수를 조작 하시겠습니까? 아니면 그냥 가정일까요? 전자를 실제로 의미하는 경우 모든 (값) 비트를 완전히 제어하려면 ** 서명되지 않은 ** 유형을 사용해야합니다. –

+0

아하, 그렇습니다. 그것은 내가 의미했던 것입니다. – Kyle

+3

일반적으로 [정수 승격] (http://en.cppreference.com/w/c/language/conversion#Integer_promotions)의 일부로 자동으로 발생합니다. 예를 들어 컴파일러에서 [일반 산술 변환] (http : /en.cppreference.com/w/c/language/conversion#Usual_arithmetic_conversions). –

답변

2

이 정말 2의 보수를 사용하여 N 비트로 표현되는 숫자로 임의의 비트 패턴을 해석에 관한 경우, 여기에 몇 가지 실수 예제 코드는 그 일의 :

#include <stdio.h> 
#include <inttypes.h> 

// this assumes the number is in the least significant `bits`, with 
// the most significat of these being the sign bit. 
int32_t fromTwosComplement(uint32_t pattern, unsigned int bits) 
{ 
    // read sign bit 
    int negative = !!(pattern & (1U << (bits-1))); 

    // bit mask for all bits *except* the sign bit 
    uint32_t mask = (1U << (bits-1)) - 1; 

    // extract value without sign 
    uint32_t val = pattern & mask; 

    if (negative) 
    { 
     // if negative, apply two's complement 
     val ^= mask; 
     ++val; 
     return -val; 
    } 
    else 
    { 
     return val; 
    } 
} 

int main(void) 
{ 
    printf("%" PRId32 "\n", fromTwosComplement(0x1f, 5)); // output -1 
    printf("%" PRId32 "\n", fromTwosComplement(0x01, 5)); // output 1 
} 
1

N 비트 2의 보수는 경우 음수 비트 n - 1은 1입니다.이 경우 1에서 n까지 31의 모든 비트를 채우고 싶습니다. 0이라면 완성을 위해 n에서 31까지의 비트를 0으로 채울 수도 있습니다. 따라서 위에서 설명한 작업을 수행하기 위해 비트 연산과 함께 사용할 수있는 마스크가 필요합니다. 이것은 쉽게 만들 수 있습니다. 비트 2의 보수가 uint32_t에서 개최하여 N 가정 :

int32_t signExtend(uint32_t number, int n) 
{ 
    uint32_t ret; 
    uint32_t mask = 0xffffffff << n; 
    if (number & (1 << (n - 1)) != 0) 
    { 
     // number is negative 
     ret = number | mask; 
    } 
    else 
    { 
     // number is positive 
     ret = number & ~mask; 
    } 
    return (int32_t) ret; 
} 

완전히 검증되지 않은 마지막 라인은 UB 수도 있지만 대부분의 구현에 작동합니다.