2012-06-27 3 views
0

val1val2에 저장된 값에서 특정 비트를 추출하고 val1val2에 해당하는 10 진수 비트를 다시 저장하려고하는 C 코드 조각이 있습니다. 나중에 val1과 val2를 비교할 수 있습니다. nbits 여기서 추출 할 비트의 범위를 2에서 2로 지정하면 세 번째 비트 만 추출됩니다. 32 비트 및 64 비트 컴퓨터에서 비트 연산

static unsigned int BIT[] = { 
0x1,  0x2,  0x4,  0x8, 
0x10,  0x20,  0x40,  0x80, 
0x100,  0x200,  0x400,  0x800, 
0x1000,  0x2000,  0x4000,  0x8000, 
0x10000, 0x20000, 0x40000, 0x80000, 
0x100000, 0x200000, 0x400000, 0x800000, 
0x1000000, 0x2000000, 0x4000000, 0x8000000, 
0x10000000, 0x20000000, 0x40000000, 0x80000000 
}; 
int val1, val2; 
unsigned long mask_val; 
int nbits[2]; 

nbits[0] = nbits[1] = 2; 
val1 = -41; 
val2 = -45; 

for (i = nbits[0]; i <= nbits[1]; i++) 
    mask_val = mask_val|BIT[i]; 
val1 = (val1 & mask_val) >> nbits[0]; 
val2 = (val2 & mask_val) >> nbits[0]; 

32 비트 시스템에 대해 원하는하지만 초기 값 val1에 저장 val2는 음 특수 64 비트 시스템에 대한 잘못된 결과를 제공로 작동 상기에이 코드

. 기계를 독립적으로 만들기 위해 위의 코드를 변경해야합니까?

+3

int 형과 long 형은 이식 가능하지 않습니다. 대신에'stdint.h' 타입을 사용하십시오 :'int32_t','uint32_t','int64_t','uint64_t'. – sfstewman

+0

@sfstewman 그게 나에게 맞는 대답 인 것 같아서, 그냥 코멘트가 아니라 그처럼 게시해야한다. –

+2

초기화하지 않으면 나를 불편하게 만든다 :'unsigned long mask_val;'하지만 나는 그것이 어떤 원인인지 모른다. 너의 문제들. – Justin

답변

3

1, 초기화되지 mask_val 많은 컴파일러 이 당신에게 문제가 발생할 stdint.h를 사용하고는 발스에 대한 유형의 마스크는 독립적 인 시스템으로합니다

int8_t 
int16_t 
int32_t 
uint8_t 
uint16_t 
uint32_t 
int64_t 
uint64_t 

3, 왜이 0x1에서뿐만 아니라 bitshift 대신 테이블 사용. ie

mask_val = mask_val| (0x1 << (i - 1)); 
+0

더 나은 :'mask_val = ~ ((1U << nbits [0]) - 1) & ((1U << nbits [1]) - 1);'그냥'for' 루프를 제거하십시오. – twalberg

+0

정말 고맙습니다.이 말이 맞는 것 같습니다. – srsci

+0

val1과 val2의 데이터 유형을 부호없는 int로 변경하면 문제가 해결 된 것 같습니다. – srsci

0

코드는 여전히 작성된 상태로 작동하지만 사용자의 부호 비트가 32 비트 마크보다 높음을 알았습니다. 이 게시물을 참조하여 도움이되는지 알려주십시오. What is the bit size of long on 64-bit Windows?

0

mask_val이 초기화되지 않았다는 문제가 있다고 생각합니다. 루프가 시작되기 전에 비트가 설정되지 않도록하려면 0으로 초기화해야합니다.

1

다양한 버전의 코드를 개발하는 동안 다른 것들은 아래에 설명 된 것과 동일한 내용을 명시했습니다.

코드가 32 비트 버전에서 작동하는 이유는 우연이라고 생각합니다. 분명히 그 시스템에서 초기화되지 않은 mask_val이 방금 제로가되었을 때, 당신은 "운이 좋았습니다".

다음은 나만의 코드 세 가지 버전의 진행 상황을 보여줍니다. 첫 번째 코드는 본질적으로 변경되지 않았지만 mask_val을 0으로 초기화하고 코드를 실행하려는 유형에 대한 typedef를 사용합니다. 두 번째는 같지만 BIT [] 테이블이 없습니다. 세 번째는 루프를 제거합니다.

#if 0 
#include <stdio.h> 

typedef long long valTy; 

int main() 
{ 
static unsigned int BIT[] = { 
0x1,  0x2,  0x4,  0x8, 
0x10,  0x20,  0x40,  0x80, 
0x100,  0x200,  0x400,  0x800, 
0x1000,  0x2000,  0x4000,  0x8000, 
0x10000, 0x20000, 0x40000, 0x80000, 
0x100000, 0x200000, 0x400000, 0x800000, 
0x1000000, 0x2000000, 0x4000000, 0x8000000, 
0x10000000, 0x20000000, 0x40000000, 0x80000000 
}; 
valTy val1, val2; 
valTy mask_val; 
int i, nbits[2]; 

printf("\n"); 

nbits[0] = nbits[1] = 2; 
val1 = -41; 
val2 = -45; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 

mask_val = 0; 
for (i = nbits[0]; i <= nbits[1]; i++) 
    mask_val = mask_val|BIT[i]; 
printf("mask_val = 0x%016llx\n\n", (long long)mask_val); 
val1 = (val1 & mask_val) >> nbits[0]; 
val2 = (val2 & mask_val) >> nbits[0]; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 
} 

#endif 




#if 0 
#include <stdio.h> 

typedef long long valTy; 
#define BIT(bitnum) (1<<bitnum) 

int main() 
{ 
valTy val1, val2; 
valTy mask_val; 
int i, nbits[2]; 

printf("\n"); 

nbits[0] = nbits[1] = 2; 
val1 = -41; 
val2 = -45; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 

mask_val = 0; 
for (i = nbits[0]; i <= nbits[1]; i++) 
    mask_val = mask_val | BIT(i); 
printf("mask_val = 0x%016llx\n\n", (long long)mask_val); 
val1 = (val1 & mask_val) >> nbits[0]; 
val2 = (val2 & mask_val) >> nbits[0]; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 
} 

#endif 

#include <stdio.h> 

typedef long long valTy; 
#define BIT(bitnum) (1<<bitnum) 

int main() 
{ 
valTy val1, val2; 
valTy mask_val; 
int i, nbits[2]; 

printf("\n"); 

nbits[0] = nbits[1] = 2; 
val1 = -41; 
val2 = -45; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 

mask_val = 0; 
{ 
    valTy maskTop = ((BIT(nbits[0])-1)<<1)|1; 
    valTy maskBottom = BIT(nbits[1])-1; 
    mask_val = maskTop & ~maskBottom; 
} 
printf("mask_val = 0x%016llx\n\n", (long long)mask_val); 
val1 = (val1 & mask_val) >> nbits[0]; 
val2 = (val2 & mask_val) >> nbits[0]; 

printf(" val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1); 
printf(" val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2); 
printf("\n"); 
} 
+0

그래, 그게 내가 온 결론이야. 'val1'과'val2'의 음수 값은 상위 비트가 설정되도록합니다 (2의 보수 표기법과 모두). 아마도 초기화되지 않은'mask_val'을 노출 할 것입니다. – sfstewman

관련 문제