2013-12-13 6 views
2

정수형을 구성하는 개별 비트를 설정해야하는 시스템에서 작업하고 있습니다.이상한 동작 설정 비트

일부 이진 연산자의 사용법을 테스트하는 프로그램을 작성했습니다. 다음은 이진 OR 연산자를 사용하여 비트를 true로 설정하는 작은 예제입니다. 그러나 그 행동은 나에게 혼란 스럽다. 루프를 통해 각 비트를 true로 설정하면 31 비트 이후에 모든 비트가 true로 설정됩니다. 왜 이것이 64 비트 머신을 사용하고 있고 비트 수를 얻기 위해 numeric_limits을 사용하고 있는지 고려할 이유가 확실치 않습니다. 다음

#include <iostream> 
#include <bitset> 
#include <limits> 

int main() { 

    typedef unsigned long long ullong; 
    ullong bits; 

    for(int i = 0; i < std::numeric_limits<ullong>::digits; ++i) { 
    bits |= (1 << i); 
    std::cout << std::bitset<std::numeric_limits<ullong>::digits>(bits) << "\n"; 
    } 

    return 0; 
} 

이 프로그램의 출력은 : 그것은 64 비트 정수로 확장 될 때 1, 정수로 등으로 처리되기 때문에

0000000000000000000000000000000000000000000000000000000000000001 
0000000000000000000000000000000000000000000000000000000000000011 
0000000000000000000000000000000000000000000000000000000000000111 
0000000000000000000000000000000000000000000000000000000000001111 
0000000000000000000000000000000000000000000000000000000000011111 
0000000000000000000000000000000000000000000000000000000000111111 
0000000000000000000000000000000000000000000000000000000001111111 
0000000000000000000000000000000000000000000000000000000011111111 
0000000000000000000000000000000000000000000000000000000111111111 
0000000000000000000000000000000000000000000000000000001111111111 
0000000000000000000000000000000000000000000000000000011111111111 
0000000000000000000000000000000000000000000000000000111111111111 
0000000000000000000000000000000000000000000000000001111111111111 
0000000000000000000000000000000000000000000000000011111111111111 
0000000000000000000000000000000000000000000000000111111111111111 
0000000000000000000000000000000000000000000000001111111111111111 
0000000000000000000000000000000000000000000000011111111111111111 
0000000000000000000000000000000000000000000000111111111111111111 
0000000000000000000000000000000000000000000001111111111111111111 
0000000000000000000000000000000000000000000011111111111111111111 
0000000000000000000000000000000000000000000111111111111111111111 
0000000000000000000000000000000000000000001111111111111111111111 
0000000000000000000000000000000000000000011111111111111111111111 
0000000000000000000000000000000000000000111111111111111111111111 
0000000000000000000000000000000000000001111111111111111111111111 
0000000000000000000000000000000000000011111111111111111111111111 
0000000000000000000000000000000000000111111111111111111111111111 
0000000000000000000000000000000000001111111111111111111111111111 
0000000000000000000000000000000000011111111111111111111111111111 
0000000000000000000000000000000000111111111111111111111111111111 
0000000000000000000000000000000001111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
+5

'1'은 정수입니다. 오버플로하고 있습니다. 대신'1ULL'을 시도하십시오. – Casey

+0

'std :: bitset'을 사용하지 않는 이유는 무엇입니까 ?? –

+0

제 1의 장소에서 사용하지 않는 이유는 무엇입니까? –

답변

3

이것은, 그 서명은 -펼친. 부호없는 정수는 대신 0 확장입니다.

이것은 정수 확장의 두 가지 다른 동작입니다. Integral Extension은 정수형이 더 큰 정수형으로 변환 될 때 일어나는 일입니다. 컴퓨터는 분명히 새로운 비트를 무작위로 만들 수 없으므로 대신 컴파일러는 두 가지 일관된 동작 중 하나를 선택합니다.

  • 로그인 확장 부호 비트를 받아 그 정수의 모든 새로운 비트를 위해 그것을 반복 : 당신이 int을 가지고 그것을 long을 할 경우, 그 방법, 그것은 여전히 ​​같은 기호 같은 수 있습니다 . 이것은 부호가있는 정수를 확장 할 때 일반적으로 발생합니다.
  • 숫자가 0 인 제로 확장 패드가 이제는 양수가됩니다 (그러나 양수일 경우에는 변경되지 않습니다). 이것은 부호 비트를 일반 숫자 비트로 처리하는 부호없는 정수를 확장 할 때 일반적으로 발생합니다. 당신이보다 더 그것을 이동하고 그렇지 않으면 1 당신이 이동 할 때 "떨어져"것입니다 때문에

또한, 1은 적어도 당신의 bits 변수로 큰 컴파일러에게해야합니다 int 크기이므로 버려집니다. 1에서 ullong ((ullong)1)을 전송하거나 더 간결하게 ull 접두사 인 1ull을 사용하여 전송할 수 있습니다.

+1

'i'는 64 비트 부호없는 정수로 변환되지 않으며, 시프트 수로 사용됩니다. – Casey

+0

예, 뒤로 가져 왔습니다. – zneak

+0

왼쪽 시프트가 부호 비트를 조작하려고 시도 할 때 일반적으로 동작은 정의되지 않습니다. 그것은 심지어 우리가 서명 된 전환을 넓히기 전에 일어납니다. 왼쪽 시프트 1 비트는 효과적으로 2 배의 배수로 처리됩니다. 배수가 기본 서명 된 유형의 범위를 벗어나면 동작은 정의되지 않습니다. 실제로 위의 코드가 보여주는 것입니다. Dieter의 대답은 언어 관점에서 올바른 답변입니다. – AnT

1

5.8 시프트 연산자

피연산자는 정수 또는 열거 범위가 지정되지 않은 타입이어야하며 일체 프로모션 행한다. 결과 형식은 승격 된 왼쪽 피연산자 입니다. 피연산자가 음수이거나 프로모션 된 왼쪽 피연산자 비트의 길이보다 크거나 같으면 동작은 정의되지 않습니다. I (1) < < 32는 정의되지 않은 동작이다 int32_t 환언 32이되면

말썽

시작.

+0

이 프로그램에서는 오른쪽이 절대로 음수가 아닙니다. – zneak