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 = 0x16
로 Flag5 = 0x10
.
답변
근거는 다를 수 있지만 제가 본 이점은 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
}
답변
이것이 바이너리 플래그 라는 것을 쉽게 알 수 있습니다 .
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
답변
시퀀스가 항상 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의 거듭 제곱을 기억하지 않고도 모든 후속 플래그를 만들 수 있습니다.
답변
때문에 [Flags]
열거 정말 있음을 의미 비트 필드 . 와 함께 [Flags]
비트 AND ( &
) 및 OR ( |
) 연산자를 사용하여 플래그를 결합 할 수 있습니다 . 이와 같은 이진 값을 다룰 때 거의 항상 16 진수 값을 사용하는 것이 더 명확합니다. 이것이 우리 가 처음에 16 진수 를 사용하는 이유 입니다. 각 16 진수 문자는 정확히 하나의 니블 (4 비트)에 해당합니다. 10 진수를 사용하면이 1-4 매핑은 사실이 아닙니다.
답변
16 진수로 2의 거듭 제곱을 두 배로 늘리는 기계적이고 간단한 방법이 있기 때문입니다. 십진수로는 어렵습니다. 머릿속에 긴 곱셈이 필요합니다. 16 진수에서는 간단한 변경입니다. 1UL << 63
십진법으로는 할 수없는 일 까지 할 수 있습니다.
답변
비트가 플래그에있는 사람을 따라가는 것이 더 쉽기 때문입니다. 각 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