2014-12-19 5 views
0

다음과 같이 작성했으며 16이 인쇄 될 것으로 예상했습니다. 열거 형의 비트 필드와 값이 저장 됨

DEMO

#include <iostream> 

enum E : long { e = 16 }; 

struct X 
{ 
    E e : 5; 
}; 

X x; 


int main(){ x.e = E::e; std::cout << static_cast<int>(x.e) << std::endl; } 

는하지만 아니었다. 컴파일러에 경고가 표시되고 대신 -16이 인쇄되었습니다. 경고 :

내게 불분명합니다. 왜 경고가 표시되었고 -16이 인쇄 되었습니까? 나는 5 크기의 비트 필드를 선언하여 거기에 16을 저장할 수 있다고 선언했습니다.

+2

형식이 서명 된 경우 5 비트로 충분하지 않습니다. 열거 형의 기본 유형을 'unsigned'로 변경하면 코드가 작동합니다. – Praetorian

+1

당신이'unsigned long'을 원한다고 생각합니다 ... http://coliru.stacked-crooked.com/a/6a1576333fd7ec55 –

답변

1

부호있는 값의 two's complement 문제입니다. 5 비트 부호가 나타내는 값의 범위를 벗어납니다.

값을 저장하는 데 5 비트 밖에없는 경우 10000이됩니다. 선행 1은 음수 값임을 나타냅니다. 부호있는 값에 대해 5 비트가있을 때만 4 비트 만 크기를 나타냅니다. 2 초 보완 값의 절대 값을 확인하려면, 당신은 모든 비트를 뒤집고 1을 추가, 그래서

10000 ->01111 - 16>10000, 그래서 귀하의 옵션에 16

것 부정적 서명 된 값 범위를 나타내려면 5 대신 6 비트를 사용하거나 unsigned long을 사용하면 크기에 대해 5 비트를 모두 사용할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 제가 알고있는 한 구현의 정의는 2의 보수 또는 부호있는 크기가 익숙한. 권리? –

+0

더 자세하게 _this 국제 표준 은 정수 형식에 대해 2의 보수, 1의 보수 및 부호 크기 표현을 허용합니다 ._ 3.9.1/8 –

+0

에서 'long'을 사용하면 부호있는 값입니다. C++에서는 부호있는 값을 2의 보수로 구현할 필요가 없지만이 값으로 표현할 수있는 값의 범위를 벗어났습니다. 'unsigned long'을 사용하면 부호없는 값이됩니다. –