Programming Language
JS33 - 12.비트 연산자, 형식화 배열, 버퍼(배열)
양찬우
2021. 6. 3. 14:00
728x90
- 컴퓨터는 모든 데이터를 이진 형식 (0,1)로 저장한다. 그 후 UTF-8과 같은 인코딩을 사용하여 저장된 비트조합을 문자,숫자, 혹은 다른 기호로 맵핑한다.
- 비트 수준에서 변수와 상호 작용하는 방법입니다. 비트는 일반적으로 부동 소수점 및 정수로 변환되므로 정보를 쉽게 소화 할 수 있습니다. 우리가 속도와 효율성을 중요시한다면 비트를 직접 처리하고 그 변환을 floats / int로 건너 뛰는 것이 유용 할 것입니다. 비트는 자바 스크립트의 변수보다 빠르지만 번역 수준을 건너 뛰는 것보다 복잡합니다.
- JS 이진 변환
Number(113).toString(2) // 1110001 // 직접 입력할 수도 있다. // function parseInt parseInt(1111, 2) //15 // 0b 0b101 //5
- 자바스크립트는 숫자를 64 비트 부동 소수점 수로 저장하지만 모든 비트 연산은 32 비트 2진수로 수행합니다.비트 연산을 수행한 후 결과는 다시 64 비트 자바스크립트 숫자로 변환됩니다.
- 비트 연산을 수행되기 전에 자바스크립트는 32 비트 부호있는 정수(signed integers)로 변환합니다.
JS 비트와이즈 연산자(Bitwise Operators)
Bitwise AND | a & b | 왼쪽 피연산자와 오른쪽 피연산자의 비트가 모두 1 인 경우 각 비트 위치에 1을 반환한다. |
Bitwise OR | a | b | 왼쪽 또는 오른쪽 피연산자의 비트가 하나 인 경우 각 비트에서 하나를 반환한다. |
Bitwise XOR | a ^ b | 한 비트의 비트가 왼쪽 피연산자와 오른쪽 피연산자 둘 다 아닌 경우 비트 위치의 1을 반환한다. |
Bitwise NOT | ~ a | 피연산자의 비트를 뒤집는다. |
왼쪽 시프트 연산 | a « b | a를 2 진수 표현 b 비트를 왼쪽으로 시프트하고 오른쪽에서 0을 시프트한다. |
부호있는 오른쪽 시프트 연산 | a » b | a를 2 진수로 b 비트를 오른쪽으로 시프트하고, 제거 된 비트를 제거한다. |
부호없는 우측 시프트 연산 | a »> b | a를 2 진수로 b 비트를 오른쪽으로 시프트하고, 시프트 오프 한 비트를 버리고, 왼쪽에서 0을 시프트한다. |
&(AND)
- && 논리 연산자와 마찬가지로, 이 연산자는 비교된 비트가 모두 1과 0이면 다른 모든 경우에 1을 반환합니다. 양쪽에서 숫자를 선택한 다음(이진 형식이 아니라 숫자) 비트를 하나 씩 비교합니다.
| (OR)
- ||과 매우 유사합니다.
- 두 이진수를 비교할 때 각 자리를 확인하고 둘 다 0이면 0 반환, 하나라도 1이면 1 반환
~ (NOT)
- 모든 비트를 반대로 한다. (양수 -> 음수, 음수 -> 양수)
- 단, ~양수를 하게 되면 결과가 -(양수+1)이 된다. 음수를 표시하려면 숫자의 비트를 바꾼 다음 1을 추가해야 한다.
^ (XOR)
- XOR 연산자 또는 독점적인 OR로 알려져 있습니다. &, | 연산자와 동일하게 비교를 하는 방식을 차별화하면서 양쪽의 숫자를 취합니다.
- ^ 연산자는 1과 0을 비교하는 특정 경우에만 1을 반환합니다.
- 각 비트를 비교하고 1이 1개만 있을 때만 1을 반환한다.
- 1 ^ 0 -> 1 , 1 ^ 1 -> 0Shifting 연산자
1. << 왼쪽 시프트
- 2를 곱하는 것과 같은 효과
- << 연산자는 숫자의 모든 비트를 n번 바꿉니다. 여기서 유의해야 할 것은 번호를 옮길 때 발생하는 빈 공간은 모두 0으로 채워져 있다는 점입니다.
2. >> 부호 유지 오른쪽 시프트
- 2로 나누는 것과 같은 효과 (나머지 버림!)
- 반면에 >> 연산자는 오른쪽으로 이동합니다. 이 변환 연산자와 이전 변환 연산자의 차이점은 이 연산자가 양의 숫자의 비트를 0초로 채우고 음의 숫자의 비트를 1로 채우는 것입니다.
base 2 : 1010 (-8 + 0 + 2 + 0 = -6) // >> 이동은 양의 숫자 비트를 0으로 채우고 음의 숫자 비트를 1로 채운다 1010 >> 1 = 1101 (-8 + 4 + 1 = -3)
- 보통 숫자의 첫 번째 부분은 표지를 나타내기 위해 사용됩니다. 1이면 음수이고, 0이면 양수입니다. 따라서 >>의 이면에 있는 추론은 우리가 움직이고 있는 숫자의 표식을 지키기 위한 것입니다.
3. >>> 부호버림 오른쪽 시프트 Zero-fill right shift
- 앞서 살펴 본 >>는 양의 숫자 비트를 0으로 채우고 음의 숫자 비트를 1로 채운다. 즉 음수는 음수, 양수는 양수를 유지한다.
- 하지만 >>>은 빈공간을 0으로 채우는 시프트다.
base 2 : 1010 (-8 + 0 + 2 + 0 = -6) // >>> 이동은 빈공간을 0으로 채운다. 1010 >>> 1 = 0101 (4 + 1 = 5) // 양수 비트 쉬프트에선 >>와 결과에 아무 차이 없다.
Binary 음수 계산
- 가장 왼쪽(가장 큰) 비트/자리 값이 음수를 나타내는 데 사용된다.
- 만약 양의 값 비트를 안다면 반전(1 -> 0 0 -> 1) 후 1을 더하면 된다.
// 4 비트 작업 시 -7표시
base 2: 1001 = 1000 + 000 + 00 + 1
aka: -7 = -8 + 0 + 0 + 1
// 양의 비트 값으로 음수 만들기
base2 : 7 = 0111
값 반전 -> 1000
1을 더함 -> 1001 (base2 -7)
// 4 비트 작업 시 -2 표시
base 2: 1110 = 1000 + 100 + 10 + 0
aka: -8 = -8 + 4 + 2 + 0
비트마스크 (mask)
- masks는 달성하려는 항목에 따라 1 또는 0으로 설정할 비트만 있는 이진 형식의 숫자입니다. 또한 변경할 비트를 정의하는 플래그로도 사용된다고 말할 수 있습니다. (1010,1000 등)
- 정수를 수동으로 추가하고 빼는 대신 비트와이즈 연산자는 각 정수를 나타내는 비트를 작업하여 직접 비교하고 조작할 수 있습니다. 따라서 0과 1에 따라 4비트 수(또는 3비트 또는 12비트)를 조작할 수 있으며, 각 비트는 ture/false 속성 중 하나를 나타냅니다.
// Let's define an object that needs to be checked. In the // real world, this might come from an API response, or user // interactions, or a form, etc. You might not know it beforehand. const myObject = { foo1: false, foo2: true, foo3: false, foo4: true } // Let's also set up some constants to make code easier to // read later on. These could obviously take many forms, or be set // up in different ways, but I find this the most intuitive to read: const HAS_FOO1 = 1; // 0001 const HAS_FOO2 = 1 << 1; // 0010 const HAS_FOO3 = 1 << 2; // 0100 const HAS_FOO4 = 1 << 3; // 1000 // Construct your bitwise number. How you do this will depend // on your use-case, but here's one way to do it: Checking object // keys manually and using if statements to add attributes one at // a time. let myBitNumber = 0; if (myObject['foo1'] === true) myBitNumber = myBitNumber | HAS_FOO1; // This uses the bitwise | to form a union if (myObject['foo2'] === true) myBitNumber = myBitNumber | HAS_FOO2; if (myObject['foo3'] === true) myBitNumber = myBitNumber | HAS_FOO3; if (myObject['foo4'] === true) myBitNumber = myBitNumber | HAS_FOO4; console.log(myBitNumber.toString(2)); // 1010 /* * Our bitwise number is now "1010". That's because our second and * fourth attributes are true. * Think of it this way: * * | fourth | third | second | first | <= Attribute * | 1 | 0 | 1 | 0 | <= True/false * */
- 위와 같은 방법으로 bitwise 값을 여러 true / false 속성을 효율적으로 저장 및 비교할 수 있다.
다른 방법 (array 사용)
728x90