"안녕, 아미고!"

"비트마스크와 XOR에 대해서도 이야기하고 싶습니다."

"숫자가 비트로 구성되어 있고 이러한 비트에서 다양한 작업을 수행할 수 있다는 것을 이미 알고 있습니다. 비트마스크는 여러 가지 다른 논리 값(참/거짓 값)을 단일 정수로 표현한 것입니다. 이 경우 각 부울 값은 특정 비트. 이것이 수행되는 방법은 다음과 같습니다."

"2의 거듭제곱(1, 2, 4, 8, 16, 32, ...)의 이진 표현은 1비트 설정만 포함합니다."

숫자 이진 표현
1 0000 0001
2 0000 0010
4 0000 0100
8 0000 1000
16 0001 0000
19(2의 거듭제곱이 아님) 0001 0011
31(2의 거듭제곱이 아님) 0001 1111

"따라서 모든 정수는 비트 배열 또는 부울 값 배열로 취급될 수 있습니다."

"하나의 숫자에 다른 부울 값을 저장하는 방법은 다음과 같습니다."

부울 값
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
하나의 숫자로 묶인 값:
int result = 0;
 if (a) result += 1; // 1 == 20 — bit 0
 if (b) result += 2; // 2 == 21 — bit 1
 if (c) result += 4; // 4 == 22 — bit 2
 if (d) result += 8; // 8 == 23 — bit 3

"이제 해당 부울 변수가 참이면 각 비트는 1입니다."

우리의 경우 변수 a와 c가 참이었으므로 결과는 1+4 == 5와 같습니다.

0000 0101
0000 dcba

"무슨 일인지 알 것 같아요."

"글쎄, 이해했다면 다음으로 넘어가자."

"int에는 32비트가 있습니다. 그 중 하나는 숫자의 부호에 사용되며 다른 31개는 31개의 부울 변수 값을 저장하는 데 사용할 수 있습니다."

"long에는 63개의 부울 변수를 저장할 수 있는 64비트가 있습니다."

"네."

"수십 개의 변수가 하나의 숫자에 몰려 있습니다. 꽤 많습니다."

"하지만 이것은 어디에 적용됩니까?"

"주로 객체에 대한 많은 정보를 저장해야 하는 상황에서. 객체에 대한 많은 정보를 저장하면 항상 수십 개의 부울 변수가 있습니다. "이러한 접근 방식을 사용하면 모두 하나의 숫자에 편리하게 저장됩니다. ."

"'저장'이라는 단어에 중점을 두고. 실제로 숫자를 사용하는 것이 그리 편리하지 않기 때문입니다."

"그나저나 그게 제가 묻고 싶었던 것입니다. 숫자에서 부울 값을 어떻게 추출합니까?"

"전혀 복잡하지 않습니다. 비트 6이 1(2의 5승은 32)으로 설정되어 있는지 확인해야 한다고 가정해 보겠습니다. 다음과 같이 확인할 수 있습니다."

숫자를 하나로 결합:
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010

int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
특정 비트를 확인하여 값 추출:
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010

"따라서 비트마스크 작업에는 세 가지 작업이 포함됩니다."

1)  특정 비트를 0으로 설정

2)  특정 비트를 1로 설정

3)  특정 비트의 값을 확인합니다.

"예를 들어 비트 6을 사용하십시오."

"비트 6을 1로 어떻게 설정합니까?"

암호 설명
result = result | 01000000;
result |= 01000000;
비트 6을 1로 어떻게 설정합니까?
result = result & 10111111;
result &= 10111111;
어떻게 비트 6을 0으로 설정합니까?
c = result & 01000000;
비트 6의 값을 어떻게 얻습니까?

"매우 이례적이지만 어렵지는 않습니다. 야, 이제 나는 핫샷 프로그래머입니다."

"01000000 또는 10111111과 같이 특정 비트가 0 또는 1로 설정된 숫자를 쉽게 얻는 방법에 대한 작은 팁이 하나 더 있습니다."

이를 위해 >> 및  << 연산자 가 있습니다  .

"1은 2의 0승입니다. 즉, 비트 0이 1로 설정된 숫자입니다. 비트 6이 설정된 숫자가 필요합니다."

int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64

"멋지다! 그런 경우에 정말 도움이 된다."

"하지만 하나의 특정 비트가 0으로 설정되는 것을 제외하고 모든 비트가 1로 설정되는 숫자가 필요한 경우 어떻게 해야 합니까?"

"그것도 어렵지 않습니다."

int d = ~(1 << 6); // ~0100 0000 == 10111111

"즉, 모든 것이 매우 간단합니다."

암호 설명
result = result | (1 << 6);
result |= (1 << 6);
비트 6을 1로 어떻게 설정합니까?
result = result & ~(1 << 6);
result &= ~(1 << 6);
어떻게 비트 6을 0으로 설정합니까?
c = result & (1 << 6);
비트 6의 값을 어떻게 얻습니까?

"별로 어려워 보이지는 않습니다. 하지만 바로 기억나지는 않을 겁니다."

"하지만 다른 사람의 코드에서 "result &= ~(1 << 6)"과 같은 무서운 표현을 발견하면 이 사람이 비트마스크를 가지고 작업하고 있다는 것을 알게 될 것입니다."

"그리고 당신이 그것을 자주 만나면 그것은 당신을 위해 스스로를 기억할 것입니다."

"기억하세요... 좋은 말씀이군요. 감사합니다."