2012-02-22 5 views
4

C에서 비트 연산자 만 사용하여 INT_MAX의 값을 얻는 방법은 무엇입니까? ~01111111111 (보조자는 이므로 십진수는 -1)이고 ~0 >> 10111111111이 될 것으로 예상했으나 최대 일 수는 있지만 여전히 -1입니다.비트 연산으로 INT_MAX 가져 오기

왜 비트 연산을 사용하여 INT_MAX의 값을 얻을 수 있습니까?

답변

9

~0UL >> 1을보십시오 : 당신이 좋아하는 뭔가를 할 수 있습니다. 문제는 서명 된 유형을 처리하는 경우 C가 부호 확장 오른쪽 시프트를 수행한다는 것입니다. 이것이 부정적인 결과를 낳는 이유입니다. 왜냐하면 거기에있는 1 비트와 일치하도록 다른 1 비트가 이동하기 때문입니다. (그런 식으로 -8 >> 1은 2로 빠른 부문에 대해 원하는만큼 -4 수 있습니다.)

+5

'~ 0UL >> 1'은 LONG_MAX입니다. '~ 0U >> 1'이 필요합니다. 어쩌면 그것을'int'로 캐스트 할 수도 있습니다. 그래서 올바른 타입을 갖습니다. – ugoren

+0

미묘하지만 좋은 점 - 어, 컴파일러의 차이점은 항상 내게 최고입니다. 문제는,이 ANSI 중 무엇입니까 또는 실제 표준이 무엇입니까? – Kaganar

+0

나는 표준이 INT_MAX를 사용한다고 말한다. 귀하의 솔루션은 2의 보수, 즉 모든 실제 CPU에서 작동합니다. 대안으로 나는'for (x = 0; x + 1> x; x ++);가 느리다는 것은 확실히 견고하다고 생각한다. – ugoren

2

음수를 오른쪽으로 이동하면 숫자의 새 비트가 1이 될 수 있습니다 (음수로 유지). 그래서 -1을 얻습니다.

편집 :

int i=1; 
while (i<<1) i<<=1; 
i=~i; 
+0

"할 수 있습니다"? 에서와 같이 모든 구현에서 아닌가? –

+1

표준에 따르면 구현에 달려 있다고합니다. – asaelr

+0

@PaulManta 오른쪽 시프트 음수는 실제로 구현 정의됩니다 (6.5.7 (5)). asaelr하지만 'E1> 2^E2'가 해당 유형에서 표현할 수없는 경우 'E1> 0'에 서명 된 유형의 값인 경우 'E1 << E2'는 정의되지 않은 동작이므로이 대안에 대한 구체적인 해석이 필요합니다. 정의되지 않은 동작. –

2

당신이 부호없는 정수로 0을 치료하는 경우, 컴파일러가 서명 변화 수행하지 않습니다 :

int i = ~0U >> 1; 

을 이것은 당신에게 줄 것이다 INT_MAX

1

(1 < < 31) -1)뿐만 아니라

. 이것은 오래된 스레드지만, 어쨌든 그것을 검색하는 사람들을 위해 게시 할 것입니다. 하지만 완전히 비트가 아니며 컴퓨터의 "int"가 32 비트라고 가정합니다.

0
#include <stdio.h> 

int main(){ 
    int max = ~0U >> 1; 
    int min = ~max; 

    printf("Max = 0x%X, min = 0x%X", max, min); 
    return 0; 
} 

출력은 :

Max = 0x7FFFFFFF, min = 0x80000000 
관련 문제