플래그 열거 형이 일반적으로 16 진수 값으로 정의되는 이유


122

16 진수 값을 사용하는 플래그 열거 형 선언을 자주 볼 수 있습니다. 예를 들면 :

[Flags]
public enum MyEnum
{
    None  = 0x0,
    Flag1 = 0x1,
    Flag2 = 0x2,
    Flag3 = 0x4,
    Flag4 = 0x8,
    Flag5 = 0x10
}

열거 형을 선언 할 때 일반적으로 다음과 같이 선언합니다.

[Flags]
public enum MyEnum
{
    None  = 0,
    Flag1 = 1,
    Flag2 = 2,
    Flag3 = 4,
    Flag4 = 8,
    Flag5 = 16
}

일부 사람들이 값을 10 진수가 아닌 16 진수로 작성하기로 선택한 이유 또는 근거가 있습니까? 내가보기에, 16 진수 값을 사용하고 실수 Flag5 = 0x16Flag5 = 0x10.


4
십진수를 사용 10하는 것보다 글을 쓸 가능성을 줄이는 것은 무엇 0x10입니까? 특히 이것들은 우리가 다루는 이진수이기 때문에 16 진수는 이진수로 /에서 사소하게 변환 할 수 있습니까? 0x111머리로 번역하는 것이 훨씬 덜 짜증납니다 273...
cHao

4
C #에 2의 거듭 제곱을 명시 적으로 작성할 필요가없는 구문이 없다는 것은 안타까운 일입니다.
패닉 대령

여기서 말도 안되는 일을하고 있습니다. 플래그의 의도는 비트 단위로 결합된다는 것입니다. 그러나 비트 조합은 유형의 요소가 아닙니다. 값 Flag1 | Flag2은 3이고 3은의 도메인 값에 해당하지 않습니다 MyEnum.
Kaz

어디에서 봅니까? 반사경으로?
giammin 2012

@giammin 특정 구현에 관한 것이 아니라 일반적인 질문입니다. 예를 들어 오픈 소스 프로젝트를 사용하거나 인터넷에서 사용할 수있는 코드 만 사용할 수 있습니다.
Adi Lester 2012

답변:


183

근거는 다를 수 있지만 제가 본 이점은 16 진수가 다음과 같이 상기시켜 준다는 것입니다. "좋아요, 인간이 발명 한 임의의 10 진법 세계에서 더 이상 숫자를 다루지 않습니다. 우리는 비트 (기계의 세계)를 다루고 있습니다. 규칙에 따라 플레이 할 것입니다. " 데이터의 메모리 레이아웃이 중요한 상대적으로 낮은 수준의 주제를 다루지 않는 한 16 진수는 거의 사용되지 않습니다. 그것을 사용하면 그것이 현재 우리가 처한 상황이라는 사실을 암시합니다.

또한 C #에 대해 잘 모르겠지만 C x << y에서 유효한 컴파일 시간 상수 라는 것을 알고 있습니다. 비트 시프트를 사용하는 것이 가장 명확 해 보입니다.

[Flags]
public enum MyEnum
{
    None  = 0,
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2,
    Flag4 = 1 << 3,
    Flag5 = 1 << 4
}

7
이것은 매우 흥미롭고 실제로 유효한 C # 열거 형이기도합니다.
Adi Lester 2012

13
+1이 표기법을 사용하면 열거 형 값 계산에서 오류가 발생하지 않습니다
Sergey Berezovskiy 2011

1
@AllonGuralnek : 컴파일러가 [Flags] 주석에 고유 한 비트 위치를 할당합니까? 일반적으로 0에서 시작하여 1 씩 증가하므로 3 (10 진수)이 할당 된 모든 열거 형 값은 이진수로 11이되어 2 비트를 설정합니다.
Eric J.

2
@Eric : 허, 왜 그런지 모르겠지만 항상 2의 거듭 제곱 값을 할당했다고 확신했습니다. 방금 확인했는데 내가 틀렸다고 생각합니다.
Allon Guralnek 2012

38
x << y표기법 에 대한 또 다른 재미있는 사실입니다 . 1 << 10 = KB, 1 << 20 = MB1 << 30 = GB. 버퍼 용으로 16KB 어레이를 만들고 싶다면 정말 좋습니다.var buffer = new byte[16 << 10];
Scott Chamberlain

43

이것이 바이너리 플래그 라는 것을 쉽게 알 수 있습니다 .

None  = 0x0,  // == 00000
Flag1 = 0x1,  // == 00001
Flag2 = 0x2,  // == 00010
Flag3 = 0x4,  // == 00100
Flag4 = 0x8,  // == 01000
Flag5 = 0x10  // == 10000

하지만 진행은 그것도 명확하게 :

Flag6 = 0x20  // == 00100000
Flag7 = 0x40  // == 01000000
Flag8 = 0x80  // == 10000000

3
실제로 0x1, 0x2, 0x4, 0x8 앞에 0을 추가합니다. 그래서 0x01, 0x02, 0x04, 0x08 및 0x10을 얻습니다. 더 읽기 쉽습니다. 내가 뭔가를 엉망으로 만들고 있습니까?
LightStriker 2011

4
@Light-전혀. 이것은 매우 일반적이므로 어떻게 정렬되는지 확인할 수 있습니다. 비트를 더 명시 적으로 만듭니다. :)
Oded

2
@LightStriker 그냥 거기 밖으로 던져하려고 하지 당신이 진수를 사용하지 않는 경우 문제. 0으로 만 시작하는 값은 8 진수로 해석됩니다. 그래서 012실제로 10입니다.
Jonathon Reinhart 2012

@JonathonRainhart : 알아요. 하지만 비트 필드를 사용할 때는 항상 16 진수를 사용합니다. int대신 사용 하는 것이 안전하다고 느낄지 모르겠습니다 . 어리석은 건 알지만 ... 습관은 힘들어.
LightStriker 2011

36

시퀀스가 항상 1,2,4,8이고 0을 더하기 때문이라고 생각합니다.
보시다시피 :

0x1 = 1 
0x2 = 2
0x4 = 4
0x8 = 8
0x10 = 16
0x20 = 32
0x40 = 64
0x80 = 128
0x100 = 256
0x200 = 512
0x400 = 1024
0x800 = 2048

등, 1-2-4-8 시퀀스를 기억하는 한 2의 거듭 제곱을 기억하지 않고도 모든 후속 플래그를 만들 수 있습니다.


13

때문에 [Flags]열거 정말 있음을 의미 비트 필드 . 와 함께 [Flags]비트 AND ( &) 및 OR ( |) 연산자를 사용하여 플래그를 결합 할 수 있습니다 . 이와 같은 이진 값을 다룰 때 거의 항상 16 진수 값을 사용하는 것이 더 명확합니다. 이것이 우리 가 처음에 16 진수 를 사용하는 이유 입니다. 각 16 진수 문자는 정확히 하나의 니블 (4 비트)에 해당합니다. 10 진수를 사용하면이 1-4 매핑은 사실이 아닙니다.


2
비트 연산을 사용하는 기능은 실제로 flags 속성과 관련이 없습니다.
Mattias Nordqvist 2013 년

4

16 진수로 2의 거듭 제곱을 두 배로 늘리는 기계적이고 간단한 방법이 있기 때문입니다. 십진수로는 어렵습니다. 머릿속에 긴 곱셈이 필요합니다. 16 진수에서는 간단한 변경입니다. 1UL << 63십진법으로는 할 수없는 일 까지 할 수 있습니다.


1
나는 이것이 가장 의미가 있다고 생각합니다. 큰 값 세트가있는 열거 형의 경우 가장 쉬운 방법입니다 (@Hypercube의 예를 제외하고 가능한 경우).
Adi Lester

3

비트가 플래그에있는 사람을 따라가는 것이 더 쉽기 때문입니다. 각 16 진수는 4 비트 바이너리에 맞을 수 있습니다.

0x0 = 0000
0x1 = 0001
0x2 = 0010
0x3 = 0011

... and so on

0xF = 1111

일반적으로 플래그가 비트와 겹치지 않도록하려면 플래그를 선언하는 데 16 진수 값을 사용하는 것이 가장 쉬운 방법입니다.

따라서 16 비트의 플래그가 필요한 경우 4 자리 16 진수 값을 사용하므로 잘못된 값을 피할 수 있습니다.

0x0001 //= 1 = 000000000000 0001
0x0002 //= 2 = 000000000000 0010
0x0004 //= 4 = 000000000000 0100
0x0008 //= 8 = 000000000000 1000
...
0x0010 //= 16 = 0000 0000 0001 0000
0x0020 //= 32 = 0000 0000 0010 0000
...
0x8000 //= 32768 = 1000 0000 0000 0000

이 설명은 좋은 ....없는 유일한 것은 비트, 니블의 궁극적 인 라인을 표시하는 이진과 동일하고, 바이트)
GoldBishop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.