정보실

웹학교

정보실

javascript JavaScript 비트 연산자에 대한 흥미로운 사용 사례(5)

본문

Zero-fill right shift (>>>) 


제로 채우기 오른쪽 시프트 (>>>) 연산자는 부호 전파 오른쪽 시프트 (>>) 연산자와 매우 유사합니다. 그러나 주요 차이점은 왼쪽에서 이동 한 비트에 있습니다.


이름에서 알 수 있듯이 0 비트는 항상 왼쪽에서 이동합니다. 결과적으로 >>> 연산자는 결과 정수의 부호 비트가 항상 0이므로 부호 없는 32 비트 정수를 항상 반환합니다. 양의 정수의 경우 >>와 >>>는 항상 동일한 결과를 반환합니다.


예를 들어, 정수 170과 -170을 고려하십시오. 오른쪽으로 3 비트를 이동 시키려면 >>> 연산자를 다음과 같이 사용할 수 있습니다.


//  170 => 00000000000000000000000010101010
// -170 => 11111111111111111111111101010110

// 170 >>> 3
// --------------------------------------------
//    (***)00000000000000000000000010101(010)
// --------------------------------------------
//  = (000)00000000000000000000000010101(***)
// --------------------------------------------
//  = 00000000000000000000000000010101
// --------------------------------------------
//  = 21 (decimal)

// -170 >>> 3
// --------------------------------------------
//    (***)11111111111111111111111101010(110)
// --------------------------------------------
//  = (000)11111111111111111111111101010(***)
// --------------------------------------------
//  = 00011111111111111111111111101010
// --------------------------------------------
//  = 536870890 (decimal)

console.log(170 >>> 3); // 21
console.log(-170 >>> 3); // 536870890

구성 플래그 


이 튜토리얼을 마무리하기 전에 비트 연산자와 비트 마스킹 (config flags)의 또 다른 일반적인 응용을 살펴 보겠습니다.


함수 실행 방법 또는 반환되는 값의 종류를 제어하는 ​​데 사용할 수 있는 몇 가지 부울 옵션을 허용하는 함수가 있다고 가정합니다. 이 함수를 생성하는 한 가지 방법은 모든 옵션을 인수로 함수에 전달하는 것입니다.


function doSomething (optA = true, optB = true, optC = false, optD = true, ...) {
  // something happens here...
}

확실히, 이것은 편리하지 않습니다. 이 접근 방식이 상당히 문제가 되는 두 가지 경우가 있습니다.

  • 부울 옵션이 10 개 이상 있다고 가정 해보십시오. 많은 매개 변수로 함수를 정의 할 수 없습니다.
  • 다섯 번째와 아홉 번째 옵션에 다른 값을 지정하고 다른 옵션은 기본값으로 남겨두고 싶다고 상상해보십시오. 함수를 호출하여 기본값을 다른 모든 옵션에 대한 인수로 전달하고 5 번째 및 9 번째 옵션에 대해 원하는 값을 전달해야 합니다.

이전 방법으로 문제를 해결하는 한 가지 방법은 다음과 같이 구성 옵션에 객체를 사용하는 것입니다.


const defaultOptions = {
  optA: true,
  optB: true,
  optC: false,
  optD: true,
  ...
};

function doSomething (options = defaultOptions) {
  // something happens here...
}

이 접근 방식은 매우 우아하며, 어떤 방식으로든 사용했거나 직접 사용했을 가능성이 높습니다. 그러나 이 방법을 사용하면 options 인수는 항상 객체이므로 구성 옵션만으로 과잉으로 간주 될 수 있습니다.


모든 옵션이 부울 값을 취하면 객체 대신 정수를 사용하여 옵션을 나타낼 수 있습니다. 이 경우 정수의 특정 비트가 지정된 옵션에 매핑됩니다. 비트가 켜져 있으면 (1로 설정) 지정된 옵션의 값이 true이고 그렇지 않으면 false입니다.


간단한 예를 사용하여 이 방법을 시연 할 수 있습니다. 숫자가 포함 된 배열 목록의 항목을 정규화하고 정규화 된 배열을 반환하는 함수가 있다고 가정합니다. 반환 된 배열은 다음 세 가지 옵션으로 제어 할 수 있습니다.

  • 분수 : 배열의 각 항목을 배열의 최대 항목으로 나눕니다.
  • 고유 : 배열에서 중복 항목을 제거합니다
  • 정렬 됨 : 배열의 항목을 최저에서 최고로 정렬


 148/5000 3 비트 정수를 사용하여 이러한 옵션을 나타낼 수 있으며 각 비트는 옵션에 매핑됩니다. 다음 코드 스니펫은 옵션 플래그를 보여줍니다.


const LIST_FRACTION = 0x1; // (001)
const LIST_UNIQUE = 0x2;   // (010)
const LIST_SORTED = 0x4;   // (100)

하나 이상의 옵션을 활성화하려면 | 필요한 경우 연산자를 사용하여 해당 플래그를 결합 할 수 있습니다. 예를 들어 다음과 같이 모든 옵션을 활성화하는 플래그를 만들 수 있습니다.


const LIST_ALL = LIST_FRACTION | LIST_UNIQUE | LIST_SORTED; // (111)

다시 말하지만 분수와 정렬 된 옵션 만 기본적으로 활성화되도록하겠습니다. 우리는 | 다음과 같이 연산자를 다시 수행하십시오.


const LIST_DEFAULT = LIST_FRACTION | LIST_SORTED; // (101)

 277/5000 이 옵션은 세 가지 옵션만으로는 나쁘지 않지만 옵션이 너무 많으면 상당히 지저분해지는 경향이 있으며 기본적으로 많은 옵션을 활성화해야 합니다. 이러한 시나리오에서 ^ 연산자를 사용하여 원하지 않는 옵션을 비활성화 하는 것이 더 나은 방법입니다.


const LIST_DEFAULT = LIST_ALL ^ LIST_UNIQUE; // (101)

여기에 모든 옵션을 활성화하는 LIST_ALL 플래그가 있습니다. 그런 다음 ^ 연산자를 사용하여 고유 옵션을 비활성화하고 필요에 따라 다른 옵션을 활성화합니다.



페이지 정보

조회 55회 ]  작성일19-08-07 17:04

웹학교