【问题标题】:Bitwise operation - Zero-fill right shift (>>>) usages?按位运算 - 零填充右移 (>>>) 用法?
【发布时间】:2013-09-29 12:10:29
【问题描述】:

一般来说,位移 (>> , <<) 允许我们除以/乘以 ^2

例子:

      9 (base 10): 00000000000000000000000000001001 (base 2)
                   --------------------------------
 9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)

对于数字:

同样,-9 >> 2 产生 -3,因为符号被保留:

     -9 (base 10): 11111111111111111111111111110111 (base 2)
                   --------------------------------
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)

但是看看>>>,它对正数的行为相同,但对负数的行为不同:

mdn

位从左边移入

我找不到任何将0 左移的原因/用法(这使得整数为正数):

       -9 (base 10): 11111111111111111111111111110111 (base 2)
                     --------------------------------
 -9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)

问题:

在什么情况下我应该使用>>> ?我不明白我为什么要从左边填充零并弄乱我的负数。

【问题讨论】:

  • 阅读 logical right shift, the >>> operator, >> 保留符号,但 >>> 不是
  • @GrijeshChauhan 这真的很有帮助,但它只解释了我已经知道的如何它的工作原理。但在什么情况下我应该使用它?我没有看到任何将这些位向右移动并添加左填充零的数学运算。我的意思是,如果我告诉你使用按位运算来除数 - 你会选择 >> 但你什么时候会选择 >>>
  • 好的,我再次阅读了您的问题。我在某处读到无符号移位在图形编程中经常使用。我不知道怎么做。所以+。
  • 阅读:Read usage of >>> 有时我们在编程中使用,例如我在my answer 中使用的这里
  • @RoyiNamir 这取决于你如何阅读(解释)11111111111111111111111111110111。我可能想用作 unsigned int 0xfffffff7 并进行右移以 divide 它。

标签: javascript binary bit-manipulation


【解决方案1】:

一个简单且经常使用的用例是将变量转换为 32 位无符号整数 (UInt32)。当您执行变量 >>> 0 时,如果变量已经是 UInt32,则该变量将保持不变,否则将为 0。例如

使用示例:

function convert( arrayLikeVariable){
   // we dont know for sure if length is UInt32
   // e.g. arrayLikeVariable.length = "zavarakatranemia"
   // so we do >>> 0
   var len = arrayLikeVariable >>> 0 
   // Now len is UInt32 for sure. 
   [..]
   // code using the len
}

如果您想要一个完整的示例,请在此处查看 Polyfill:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

if (!Array.prototype.indexOf)  Array.prototype.indexOf = (function(Object, max, min){
  "use strict";
  return function indexOf(member, fromIndex) {
    if(this===null||this===undefined)throw TypeError("Array.prototype.indexOf called on null or undefined");

    var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len);
    if (i < 0) i = max(0, Len+i); else if (i >= Len) return -1;

    if(member===void 0){ for(; i !== Len; ++i) if(that[i]===void 0 && i in that) return i; // undefined
    }else if(member !== member){   for(; i !== Len; ++i) if(that[i] !== that[i]) return i; // NaN
    }else                           for(; i !== Len; ++i) if(that[i] === member) return i; // all else

    return -1; // if the value was not found, then return -1
  };
})(Object, Math.max, Math.min);

【讨论】:

    【解决方案2】:

    假设您正在编写一些东西来模仿硬件,特别是shift register

    为了方便起见,我将使用 8 位而不是您问题中的 32 位。

    每次我们想向这个移位寄存器输入一个高位时,我们可以添加 128,因为它会使最左边的位变为 1。

    // Assume n is initialised to 0, so n = 00000000 in binary
    n += 128;                    // now n = 10000000 in binary
    

    如果我们每次你想模拟一个时钟周期时都使用 >>> 进行移位,那么在 8 个“时钟周期”之后,我们将在最右边有那个 1。如果我们读出最右边的位,那么我们将得到 8 个周期前馈入最左边的位的延迟版本。


    这只是位不被解释为数字的一个例子,我相信还有更多。我认为您会在其他地方找到更多用途,尤其是在旨在模仿硬件电路/构建块的软件中。

    【讨论】:

      猜你喜欢
      • 2011-02-08
      • 2015-10-13
      • 1970-01-01
      • 2022-07-22
      • 2011-05-08
      • 2015-04-07
      • 1970-01-01
      • 2017-04-29
      • 2015-10-24
      相关资源
      最近更新 更多