2016-09-15 11 views
2

나는 size_t로 정수로 적당히 많은 수의 추가 시프트 연산자를 사용하는 이전 프로그래머를 편집하고있다. 디버깅 목적으로이 특정 정수를 가지고 놀았을 때 나는 그 숫자를 변경하는 것이 예측 가능한 결과를 가져 오지 않는다는 것을 발견했다.왜 Shift 연산자 (C++)로 임의의 결과가 표시됩니까? 코드에서

입력 :

std::size_t 
    foo1 = 100000 << 20, 
    foo2 = 200000 << 20, 
    foo3 = 300000 << 20, 
    foo4 = 400000 << 20; 
std::cout << "foos1-4:"; 
std::cout << foo1; 
std::cout << foo2; 
std::cout << foo3; 
std::cout << foo4; 

수율 :

foos1-4: 
1778384896 
18446744072971354112 
1040187392 
18446744072233156608 

는 난이 오버플로 오류의 일종이지만, (내 인정 하듯이 제한 지식)를 size_t는 사람들이 안 알아. 내가 알고있는 바로는 size_t는 사실상 무제한의 정수를 저장할 수있는 부호없는 정수형이다. 이 코드는 2^20 (1048576)에 의해 수를 곱해야 비트 쉬프트 연산자 이해 것과

. 이 사이트의 다른 페이지 링크 : What are bitwise shift (bit-shift) operators and how do they work?

주 - 나는 foo1은 32 진 자리 절단과 오버플로 오류로 나타납니다 손에 의해 작동했지만 모든 사람은 나에게 완전히 무작위로 보인다.

http://en.cppreference.com/w/cpp/types/size_t : std :: size_t는 이론적으로 가능한 모든 유형의 객체 (배열 포함)의 최대 크기를 저장할 수 있습니다. 이 문제는 정수가 선언되는 방식이나 비트 시프트가 작동하는 방식에 문제가 있다고 가정합니다.

무슨 일 이니?

+0

'size_t'는 "사실상 무제한"이 아닙니다. 임의의 객체의 크기 *를 바이트 단위로 나타 내기에 충분할만큼 크기가 보장됩니다. 실제로, (http://en.cppreference.com/w/cpp/types/numeric_limits/max#Example) 구현 18446744073709551615' '의 최대 값을 갖는다 cppreference 예에서 코드를 컴파일하는 데, 그러나이다 실제로 필요한 최소값보다 훨씬 큽니다. –

답변

11

문제는되지 std::size_t하지만 int 리터럴은 사용.

#include <iostream> 

int main() 
{ 
std::size_t 
    foo1 = 100000UL << 20, 
    foo2 = 200000UL << 20, 
    foo3 = 300000UL << 20, 
    foo4 = 400000UL << 20; 
std::cout << "foos1-4:" << std::endl; 
std::cout << foo1 << std::endl; 
std::cout << foo2 << std::endl; 
std::cout << foo3 << std::endl; 
std::cout << foo4 << std::endl; 
} 

출력 :

foos1-4: 
104857600000 
209715200000 
314572800000 
419430400000 

Live Demo


이 또한 컴파일러는 그것에 대해 정확히 당신에게 경고를 제공주의 :

당신은 그들이 오랫동안 여기처럼 UL 접미사를 사용하여 만들 수 있습니다
main.cpp:6:19: warning: result of '(100000 << 20)' requires 38 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=] 
    foo1 = 100000 << 20, 
      ~~~~~~~^~~~~ 
main.cpp:7:19: warning: result of '(200000 << 20)' requires 39 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=] 
    foo2 = 200000 << 20, 
      ~~~~~~~^~~~~ 
main.cpp:8:19: warning: result of '(300000 << 20)' requires 40 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=] 
    foo3 = 300000 << 20, 
      ~~~~~~~^~~~~ 
main.cpp:9:19: warning: result of '(400000 << 20)' requires 40 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=] 
    foo4 = 400000 << 20; 
      ~~~~~~~^~~~~