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.
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 >>.
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.
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.
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.
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.
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With