2012-04-06 3 views
5

아주 간단한 질문이지만, 아마도 나는 단지 뭔가를 잊어 버리고 있습니다. 64 비트 리눅스에서 8bytes 길이가 길습니까? 그런 경우, 나는 64 비트를 설정하려면 , 나는 다음을 수행 할 수 있습니다 :이 컴파일 할 때마다롱 타입 64 비트 리눅스

unsigned long num = 1<<63; 

은, 그러나, 그것이 내가 이상으로 이동 왼쪽 해요 말하는 나에게 오류를 제공 넓이. 나는 (부호 확장없이) 긴 형식의 첫 번째 32 비트을하기를 원한다면 또한, 내가 할 수있는 :

num = num&0xFFFFFFFF; 

또는 무엇에 대해 :

num = (int)(num); 

감사합니다.

+5

시도를 사용하여'부호없는 긴 NUM = 1UL를 << 63;' – Mysticial

+0

@Mysticial 왜 게시와 정수 프로모션 물건과 함께 답변? – cnicutar

+1

사용되는 컴파일러에 따라 다릅니다. 많은 레거시 컴파일러는 64 비트 시스템에서 실행되는 경우에도 기본적으로 32 비트 long으로 설정됩니다. 더 많은 것을 시도하기 전에'sizeof num '이 8인지 확인하십시오. – wallyk

답변

3

64 비트 리눅스에서는 8bytes가 깁니까?

아니요. 기본 OS보다 컴파일러에 의존합니다. 좋은 토론이 있는지 확인하십시오. 나는이 컴파일 할 때마다, 그러나, 더

모두가 이미 대답 한 폭보다 나에게 내가 에 의해 이동 왼쪽 해요 없다는 오류를 제공 What decides the sizeof an integer?

. 나는 ( 부호 확장하지 않음) 유형의 첫 번째 32 비트를 가져 가고 싶어하면 나는 할 수있다, 또한 1UL

을 사용

num = num&0xFFFFFFFF; 
or what about: 

num = (int)(num); 

num = num&0xFFFFFFFF합니다. 그러면 하위 32 비트가 제공됩니다. 그러나 long이 시스템에서 4 바이트 인 경우 전체 번호이 표시됩니다. 부호 확장 부분에 와서 long을 사용하고 unsigned long이 아닌 경우 부호 확장 비트를 제거 할 수 없습니다. 예를 들어, -1은 0 번째 비트부터 모든 1로 표시됩니다. 마스킹으로 어떻게 이들을 피할 수 있습니까? 이 몇 년 전 ReiserFS와의 주요 버그의 소스처럼 numint

+0

C가 64 비트 시스템에서 64 비트가되도록 'long'을 부과하지 않는다고 동의합니다. 그러나 리눅스는 그것을 암묵적으로 부과합니다. 'unsigned long'을 통해 전달 된 모든 포인터와 'signed long'을 통해 전달 된 메모리 오프셋 (예 : syscalls)을 살펴보십시오. 그러므로 리눅스 소스 코드가 크게 바뀌지 않는 한 ** yes **로 대답 할 것입니다 : "64 비트 리눅스에서'long '은 8 바이트입니다. 맞습니까? –

0

저는 첫 번째 질문의 문제점은 컴파일러가 '1'을 정수가 아닌 긴 정수로 취급한다고 생각합니다. 그것은 임무가 끝날 때까지 알아 내지 못합니다. , int32_t 당신이 당신의 정수에 대한 (비트) 약간의 정확한 길이를 원하는 경우 C99 부합하는 컴파일러, #include <stdint.h> 가정, 사실

unsigned long num = (unsigned long)1<<63; 
+0

내 질문의 두 번째 부분에 대한 답을 알고 계십니까? 비 부호 확장 첫 32 비트를 얻는 방법에 대해? num = num & (unsigned long) (0xFFFFFFFF)와 비슷한 것을할까요? – de1337ed

+0

@ de1337ed Qn의 두 번째 부분에 답했습니다. 체크 아웃 –

4

int64_t 같은 유형을 사용 :

당신은 수행하여 문제를 해결할 수 있습니다 등 편리한 유형은 intptr_t, 당신이 사용할 수있는 이식성을 void* 포인터로 동일한 비트 수 (당신이 기계 "단어"를 호출 할 수 있도록)

+1

C99 준수 컴파일러는 고정 폭 타입을 제공 할 필요가 없습니다. 'int64_t'. 패딩 비트가없는 8 비트, 16 비트, 32 비트 및 64 비트 정수 타입을 제공하는 2 보수 만 구현하면 'stdint.h'에 고정 폭 정수 typedef를 제공해야합니다. – dreamlax

1

와 정수 유형 :

#define LNG_BIT (sizeof(long) * CHAR_BIT) 

unsigned long num = 1UL << (LNG_BIT - 1); 

limits.h 얻으려면 "낮은 INT"?

#define INT_BIT (sizeof(int) * CHAR_BIT) 

if (LNG_BIT > INT_BIT) 
    return num & (~0UL >> INT_BIT); 
else 
    return num; 

또는

num &= ~(~0U << INT_BIT); 

또는 사용 마스크 같은 것을, 등등. 왜, 무엇을 위해, 등 원하는지에 따라 크게 다릅니다. int 비트.

컴파일러에서 제공하는 옵션에 주목하십시오. 나는. 당신은 GCC를 사용하는 경우 :

-m32
-m64
-mx32
        32 비트 코드를 생성하거나 64 비트 환경.
        * -m32 옵션은 int, long 및 포인터 유형을 32 비트로 설정하고 모든 i386 시스템에서 실행되는 코드를 생성합니다.
        * -m64 옵션은 int를 32 비트로, long 및 포인터 유형을 64 비트로 설정하고 x86-64 아키텍처 용 코드를 생성합니다. Darwin의 경우 -m64 옵션 만 -fno-pic 및 -mdynamic-no-pic 옵션을 해제합니다.
        * -mx32 옵션은 int, long 및 포인터 유형을 32 비트로 설정하고 x86-64 아키텍처 용 코드를 생성합니다.


        긴 주소 모드에 대한 코드를 생성 긴 -maddress-mode=long

-maddress 모드는 =도있다. 이 기능은 64 비트 및 x32 환경에서만 지원됩니다. 64 비트 환경의 경우 기본 주소 모드입니다.

0

AFAIR 코드에 맞지 않는 경우 오버플로 예외 경고를 통해

num = (int)(num) 당신에게 낮은 32 비트를 제공하지만 컴파일러는 수도 :

당신이 x86_64의 이야기 경우
unsigned long num = 1<<63; 

, 그래, 긴 64 비트와 너무 다른 대부분의 64 비트 리눅스 plytforms에있다.문제는 코드에있는 163이 모두 간단하므로 int이므로 결과는 정의되지 않습니다. 더 나은

unsigned long num = 1UL<<63; 

또는

unsigned long num = (unsigned long)1<<63; 
관련 문제