Programing

JavaScript에서 비트 연산자를 어디에서 사용합니까?

crosscheck 2020. 11. 3. 07:39
반응형

JavaScript에서 비트 연산자를 어디에서 사용합니까?


나는 '비트 연산자는 무엇입니까?'를 읽었습니다. , 그래서 나는 비트 연산자무엇인지 알고 있지만 어떻게 사용할 수 있는지 아직 명확하지 않습니다. 누구든지 JavaScript에서 비트 연산자가 유용한 실제 사례를 제공 할 수 있습니까?

감사.

편집하다:

그냥 파고 의 jQuery 소스 내가, 비트 연산자가 사용되는 장소의 몇 가지를 발견 예를 들어 한 (만 & 연산자)

// Line 2756:
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

// Line 2101
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;

예:

16 진수 값을 구문 분석하여 RGB 색상 값을 가져옵니다.

var hex = 'ffaadd';
var rgb = parseInt(hex, 16); // rgb is 16755421


var red   = (rgb >> 16) & 0xFF; // returns 255
var green = (rgb >> 8) & 0xFF;  // 170
var blue  = rgb & 0xFF;     // 221  

나는 무겁게 때로는 빠르게 자신보다 훨씬이기 때문에, 생산 스크립트에서 숫자 convertions에 대한 비트 연산자를 사용 Math또는 parseInt등가물.

내가 지불해야하는 대가는 코드 가독성 입니다. 그래서 저는 보통 Math개발에 사용 하고 프로덕션에 비트 단위로 사용합니다.

jsperf.com에서 몇 가지 성능 트릭을 찾을 수 있습니다 .

당신이 볼 수 있듯이, 브라우저는 최적화하지 않습니다 Math.ceilparseInt그래서 비트는 일을 빠르고 짧은 방법이 될 것입니다 예측 년 furure에서뿐만 아니라를 .

SO에 대한 추가 읽기 ...


보너스 : 치트 시트 에 대한 | 0정수로 변환 무엇이든 쉽고 빠른 방법 :

( 3|0 ) === 3;             // it does not change integers
( 3.3|0 ) === 3;           // it casts off the fractional part in fractionalal numbers
( 3.8|0 ) === 3;           // it does not round, but exactly casts off the fractional part
( -3.3|0 ) === -3;         // including negative fractional numbers
( -3.8|0 ) === -3;         // which have Math.floor(-3.3) == Math.floor(-3.8) == -4
( "3"|0 ) === 3;           // strings with numbers are typecast to integers
( "3.8"|0 ) === 3;         // during this the fractional part is cast off too
( "-3.8"|0 ) === -3;       // including negative fractional numbers
( NaN|0 ) === 0;           // NaN is typecast to 0
( Infinity|0 ) === 0;      // the typecast to 0 occurs with the Infinity
( -Infinity|0 ) === 0;     // and with -Infinity
( null|0 ) === 0;          // and with null,
( (void 0)|0 ) === 0;      // and with undefined
( []|0 ) === 0;            // and with an empty array
( [3]|0 ) === 3;           // but an array with one number is typecast to number
( [-3.8]|0 ) === -3;       // including the cast off of the fractional part
( [" -3.8 "]|0 ) === -3;   // including the typecast of strings to numbers
( [-3.8, 22]|0 ) === 0     // but an Array with several numbers is typecast to 0
( {}|0 ) === 0;                // an empty object is typecast to 0
( {'2':'3'}|0 ) === 0;         // or a not empty object
( (function(){})|0 ) === 0;    // an empty function is typecast to 0 too
( (function(){ return 3;})|0 ) === 0;

그리고 나를위한 마법 :

3 | '0px' === 3;

JavaScript에서는 이중 비트 부정 ( ~~n)을 Math.floor(n)( n양수인 경우) 또는 parseInt(n, 10)( n음수 인 경우에도 ) 대체로 사용할 수 있습니다 . n|n그리고 n&n항상 같은 결과를 얻을 ~~n.

var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3

// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4

단일 비트 부정 ( ~)이 계산 -(parseInt(n, 10) + 1)하므로 두 개의 비트 부정이 반환 -(-(parseInt(n, 10) + 1) + 1)됩니다.

이 세 가지 대안 n|n중 가장 빠른 것으로 보입니다 .

업데이트 : 더 정확한 벤치 마크 : http://jsperf.com/rounding-numbers-down

( 이상한 언어 기능 에 게시 된대로 )


실생활의 :

^I/O토글 러 로서의 비트 XOR

같이 사용하는 value ^= 1모든 호출에 의지 변화 value0, 1, 0, 1 ...

function toggle(evt) {
  evt.target.IO ^= 1;                                    // Bitwise XOR as 1/0 toggler
  evt.target.textContent = evt.target.IO ? "ON" : "OFF"; // Unleash your ideas
}

document.querySelectorAll("button").forEach( el =>
  el.addEventListener("click", toggle)
);
<button>OFF</button>
<button>OFF</button>
<button>OFF</button>


자바 스크립트의 발전을 감안할 때 (특히 js로 서버 측 프로그래밍을 허용하는 nodejs에서) JS에는 점점 더 복잡한 코드가 있습니다. 다음은 비트 연산자를 사용한 몇 가지 인스턴스입니다.

  • IP 주소 작업 :

    //computes the broadcast address based on the mask and a host address
    broadcast = (ip & mask) | (mask ^ 0xFFFFFFFF)
    
    
    //converts a number to an ip adress 
    sprintf(ip, "%i.%i.%i.%i", ((ip_int >> 24) & 0x000000FF),
                             ((ip_int >> 16) & 0x000000FF),
                             ((ip_int >>  8) & 0x000000FF),
                             ( ip_int        & 0x000000FF));
    

참고 : 이것은 C 코드이지만 JS는 거의 동일합니다.

  • CRC 알고리즘은 그것들을 많이 사용합니다.

이것에 대한 wikipedia 항목확인하십시오.

  • 화면 해상도 작업

숫자가 홀수인지 확인하려면 :

function isOdd(number) {
    return !!(number & 1);
}

isOdd(1); // true, 1 is odd
isOdd(2); // false, 2 is not odd
isOdd(357); // true, 357 is odd

모듈러스보다 빠름-성능 중요한 곳에 사용하십시오 !


비트 not 및 double 비트 not을 사용하는 방법에 대한 몇 가지 다른 예 :

바닥 작업

~~2.5    // 2
~~2.1    // 2
~~(-2.5) // -2

indexOf가 -1을 반환했는지 확인

var foo = 'abc';
!~foo.indexOf('bar'); // true

부울 값을 뒤집는 데 사용할 수 있습니다.

var foo = 1;
var bar = 0;
alert(foo ^= 1);
alert(bar ^= 1);

이것은 약간 어리석은 일이며 대부분의 경우 비트 연산자에는 Javascript에 많은 응용 프로그램이 없습니다.


var arr = ['abc', 'xyz']

쓰기 짜증

if (arr.indexOf('abc') > -1) {
  // 'abc' is in arr
}

if (arr.indexOf('def') === -1) {
  // 'def' is not in arr
}

무언가가 배열 안에 있는지 확인하려면?

다음 ~과 같이 비트 연산자를 사용할 수 있습니다 .

if (~arr.indexOf('abc')) {
  // 'abc' is in arr
}

if (! ~arr.indexOf('def')) {
  // 'def' is not in arr
}

비트 마스크 .

예를 들어 JS 이벤트에서 광범위하게 사용됩니다.


권한 위젯에 한 번 사용했습니다 . 유닉스의 파일 권한은 비트 마스크이므로 파싱하려면 비트 연산을 사용해야합니다.


Uint16Array에 다차원 배열을 저장하는 방법으로 세 개의 숫자를 1로 평면화하는 데 사용하고 있습니다 . 다음은 제가 개발중인 복셀 게임의 일부입니다.

function Chunk() {
  this._blocks = new Uint16Array(32768);
  this._networkUpdates = [];
}

Chunk.prototype.getBlock = function(x, y, z) {
  return this._blocks[y + (x << 5) + (z << 10)];
};

Chunk.prototype.setBlock = function(x, y, z, value) {
  this._blocks[y + (x << 5) + (z << 10)] = value;
  this._networkUpdates.push(value + (y << 15) + (x << 20) + (z << 25));
};

Chunk.prototype.getUpdates = function() {
  return this._networkUpdates;
};

Chunk.prototype.processUpdate = function(update) {
  // this._blocks[Math.floor(update / 65536)] = update % 65536;
  this._blocks[update >> 16] = update & 65535;
};

var chunk = new Chunk();
chunk.setBlock(10, 5, 4);
alert(chunk.getBlock(10, 5, 4));
alert(chunk.getUpdates()[0]);


이 답변에는 Mark의 답변에 대한 설명이 포함되어 있습니다 .

이러한 설명을 읽고 코드 조각을 실행하면 아이디어를 얻을 수 있습니다.

var hex = 'ffaadd';
var rgb = parseInt(hex, 16); // rgb value is 16755421 in decimal = 111111111010101011011101 in binary = total 24 bits


var red   = (rgb >> 16) & 0xFF; // returns 255
var green = (rgb >> 8) & 0xFF;  // returns 170
var blue  = rgb & 0xFF;         // returns 221  

// HOW IS IT

// There are two bitwise operation as named SHIFTING and AND operations.
// SHIFTING is an operation the bits are shifted toward given direction by adding 0 (zero) bit for vacated bit fields.
// AND is an operation which is the same with multiplying in Math. For instance, if 9th bit of the given first bit-set is 0
// and 9th bit of the given second bit-set is 1, the new value will be 0 because of 0 x 1 = 0 in math.

// 0xFF (000000000000000011111111 in binary) - used for to evaluate only last 8 bits of a given another bit-set by performing bitwise AND (&) operation. 
// The count of bits is 24 and the first 16 bits of 0xFF value consist of zero (0) value. Rest of bit-set consists of one (1) value.
console.log("0xFF \t\t\t\t: ", 0xFF) 


// 111111111010101011011101 -> bits of rgb variable
// 000000000000000011111111 -> 255 after (rgb >> 16) shifting operation
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000011111111 -> result bits after performing bitwise & operation
console.log("Red - (rgb >> 16) & 0xFF \t: ", (rgb >> 16) & 0xFF) // used for to evaluate the first 8 bits

// 111111111010101011011101 -> bits of rgb variable
// 000000001111111110101010 -> 65450 -> 'ffaa'
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000010101010 -> result bits after performing bitwise & operation
// calculation -> 000000001111111110101010 & 000000000000000011111111 = 000000000000000010101010 = 170 in decimal = 'aa' in hex-decimal
console.log("Green - (rgb >> 8) & 0xFF \t: ", (rgb >> 8) & 0xFF) // used for to evaluate the middle 8 bits 

// 111111111010101011011101 -> 'ffaadd'
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000011011101 -> result bits after performing bitwise & operation 
// calculation -> 111111111010101011011101 & 000000000000000011111111 = 221 in decimal = 'dd' in hex-decimal
console.log("Blue - rgb & 0xFF \t\t: ", rgb & 0xFF) // // used for to evaluate the last 8 bits.

console.log("It means that `FFAADD` hex-decimal value specifies the same color with rgb(255, 170, 221)")

/* console.log(red)
console.log(green)
console.log(blue) */


They seem to be very useful when you work with hex values and bits. Since 4 bits can represent 0 to F.

1111 = F 1111 1111 = FF.


Example using Node.js

Presuming you had a file (called multiply.js) with these contents, you could run

`node multiply <number> <number>`

and get an output consistent with using the multiplication operator on the same two numbers. The bit shifting going on in the Mulitply function is an example of how to take the bit mask representing one number and use it to flip bits in another number for fast operations.

var a, b, input = process.argv.slice(2);

var printUsage = function() {
  console.log('USAGE:');
  console.log('  node multiply <number> <number>');
}

if(input[0] === '--help') {+
  printUsage();
  process.exit(0);
}

if(input.length !== 2) {
  printUsage();
  process.exit(9);
}

if(isNaN(+input[0]) || isNaN(+input[1])) {
  printUsage();
  process.exit(9);
}

// Okay, safe to proceed

a = parseInt(input[0]),
b = parseInt(input[1]);

var Multiply = function(a,b) {
  var x = a, y = b, z = 0;

  while( x > 0 ) {
    if(x % 2 === 1) {
      z = z + y;
    }
    y = y << 1;
    x = x >> 1;
  }

  return z;
}

var result = Multiply(a,b);

console.log(result);

I just found this question trying to confirm if the bitwise AND operator also was & in Javascript.

Since you asked for an example:

if ($('input[id="user[privileges]"]').length > 0) {
    $('#privileges button').each(function () {
        if (parseInt($('input[id="user[privileges]"]').val()) & parseInt($(this).attr('value'))) {
            $(this).button('toggle');
        }
    });
}

It populates the state of buttons with jQuery given a bitmask value of a hidden field:

  • none = 0
  • user = 1
  • administrator = 2
  • user + administrator = 3

참고URL : https://stackoverflow.com/questions/654057/where-would-i-use-a-bitwise-operator-in-javascript

반응형