Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise operation - Zero-fill right shift (>>>) usages?

Generally speaking, bit shifting (>> , <<) allows us to divide / multiply by ^2

Example :

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

For negative numbers :

Likewise, -9 >> 2 yields -3, because the sign is preserved:

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

But looking at >>> which acts the same for positive numbers, but behaves differently for negative numbers :

mdn

Zero bits are shifted in from the left

I can't find any reason / usage for shifting 0 from the left ( which makes the whole number positive) from the left :

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

Question :

In what scenarios should I use >>> ? I don't understand why should I ever want to pad zeros from the left and mess my negative number.

like image 806
Royi Namir Avatar asked Sep 29 '13 12:09

Royi Namir


People also ask

What is bitwise zero fill right shift operator?

Bitwise Zero Fill Right Shift Operator shifts the bits of the number towards the right a specified n number of positions. The sign bit filled with 0's. The symbol >>> represents the Bitwise Zero Fill Right Shift Operator. When we apply >>> on a positive number, it gives the same output as that of >>.

Will perform a right shift with zero fill?

Zero-fill right shift (>>>) operator: The operator shifts the bits of the first operand by a number of bits specified by the second operand. The bits are shifted to the right and those excess bits are discarded, while 0 bit is added from left.

How do I use bitwise right shift?

The signed right shift operator '>>' uses the sign bit to fill the trailing positions. For example, if the number is positive then 0 will be used to fill the trailing positions and if the number is negative then 1 will be used to fill the trailing positions. In Java, negative numbers are stored as 2's complement.

What is the use of right shift operator?

The bitwise shift operators are the right-shift operator ( >> ), which moves the bits of an integer or enumeration type expression to the right, and the left-shift operator ( << ), which moves the bits to the left.


2 Answers

A simple and often use case is to convert a variable to 32-bit unsigned integer(UInt32). When you do variable >>> 0, the variable will stay the same if it is already a UInt32 and will be 0 if it is not. e.g.

enter image description here

using example:

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
}

If you want a complete example see the Polyfill here:

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);
like image 162
Thomas Karachristos Avatar answered Oct 09 '22 05:10

Thomas Karachristos


Let's say you were programming something to mimic a piece of hardware, specifically a shift register.

To make things easier I'll use 8 bits instead of 32 bits as in your question.

We can add 128 every time we want to feed a high bit into this shift-register, since it will make the leftmost bit 1.

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

If we shift using >>> every time you want to simulate a clock cycle, then after 8 "clock cycles" we will have that 1 at the rightmost bit. If we read that rightmost bit out then we will get a delayed version of what was fed into the leftmost bit 8 cycles ago.


This is only one example where the bits are not interpreted as a number, and I am sure there are many more. I think you'll find a few more uses elsewhere, especially in software meant to mimic hardware circuits/building blocks.

like image 20
DevGoldm Avatar answered Oct 09 '22 05:10

DevGoldm