代码之家  ›  专栏  ›  技术社区  ›  James

在JavaScript中我在哪里使用位运算符?

  •  65
  • James  · 技术社区  · 15 年前

    我读过 'what are bitwise operators?' ,所以我知道 什么 bitwise operators

    谢谢

    编辑:

    只是深入研究一下 jQuery source 我发现有几个地方使用了按位运算符,例如:(只有&运算符)

    // 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 回复  |  直到 7 年前
        1
  •  72
  •   timetowonder    7 年前

    例子:

    解析十六进制值以获取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  
    
        2
  •  47
  •   Community paulsm4    7 年前

    在生产脚本中使用按位运算符进行数字转换,因为有时它们的速度要比它们的速度快得多 Math parseInt

    我必须付出的代价是 代码易读性 . 所以我通常用 数学 在开发和生产方面。

    You can find some performance tricks on jsperf.com .

    正如您所见,浏览器不会进行优化 Math.ceil 帕森特 多年来,所以我预测按位将是更快、更短的做事方式 in furure as well .

    Some further reading on 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;
    
        3
  •  25
  •   Community paulsm4    7 年前

    在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 appears to be the fastest

    更新: http://jsperf.com/rounding-numbers-down

    (张贴于 Strangest language feature )

        4
  •  21
  •   Community paulsm4    4 年前

    现实生活 example :

    ^ 按位异或作为 I/O 扳机

    value ^= 1 每次打电话都会改变 value 0, 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>
        5
  •  16
  •   Bogdan Gavril MSFT    11 年前

    考虑到Javascript的进步(特别是允许使用js进行服务器端编程的nodejs),js中的代码越来越复杂。以下是我使用位运算符的几个实例:

    • //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几乎相同

    查看 wikipedia entry 关于这个

    • 屏幕分辨率操作
        6
  •  14
  •   danwellman    7 年前

    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
    

    比模数快-在性能要求的地方使用 计数!

        7
  •  11
  •   John Weisz    8 年前

    关于如何使用按位not和双按位not的其他几个示例:

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

    检查indexOf是否返回-1

    var foo = 'abc';
    !~foo.indexOf('bar'); // true
    
        8
  •  10
  •   Andrew Hare    15 年前

    可以使用它们翻转布尔值:

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

    不过这有点傻,而且大部分按位运算符在Javascript中没有很多应用程序。

        9
  •  7
  •   Yann Bertrand    7 年前
    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
    }
    
        10
  •  4
  •   Yuval Adam    15 年前

    Bitmasks .

    例如,在JS事件中广泛使用。

        11
  •  3
  •   troelskn    15 年前

    我曾经用过一次 permissions widget

        12
  •  2
  •   Bardi Harborow Wes Miller    9 年前

    我使用它们将三个数字展平为1,作为一种将多维数组存储在 Uint16Array . 下面是我正在开发的体素游戏的一个片段:

    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]);
        13
  •  2
  •   efkan    6 年前

    此答案包含对以下问题的解释: Mark's answer

    通过阅读这些解释并运行代码片段,可以获得一个想法。

    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) */
        14
  •  0
  •   eternauta    11 年前

    当您使用十六进制值和位时,它们似乎非常有用。因为4位可以表示0到F。

        15
  •  0
  •   mysterlune    9 年前

    假设您有一个包含这些内容的文件(称为multiply.js),您可以运行

    `node multiply <number> <number>`
    

    并得到与对相同的两个数字使用乘法运算符一致的输出。钻头的移动正在进行中 Mulitply 函数是如何获取表示一个数字的位掩码并使用它翻转另一个数字中的位以进行快速操作的示例。

    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);
    
        16
  •  -1
  •   Alix Axel    11 年前

    我刚刚发现这个问题是为了确认 AND & 在Javascript中。

    既然你要举个例子:

    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');
            }
        });
    }
    

    • none = 0
    • user 1
    • administrator = 2
    • 使用者 + = 3