0

I'm trying to understand the following code, found in MDN and in an answer of this related question. (Tested in FF 30 only.)

function createBinaryString (nMask) {
    // nMask must be between -2147483648 and 2147483647
    for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
        nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
    return sMask;
}
var p = createBinaryString(7);
console.log(p); //"00000000000000000000000000000111"

This one is on MDN, but how does this work - I'd appreciate any understandable explanation. I have basic knowledge of binary operators and know, that there is a .toString(2) method. But what does the String(nShifted >>> 31) part do exactly?

Here are better readable versions, but the first one does not work. Here I also would appreciate any suggestion about what I'm doing wrong. I can't see any difference to the second, working version.

var re = '';
var numb = 7;
var shiftBuf = numb;
for (var i = 0; i < 32; i++); {
   re += String(shiftBuf >>> 31);
   shiftBuf <<= 1;
}
console.log(re); //"0" 

var result = '';
var num = 7;
var shiftBuffer = num;
for (var i = 0; i < 32; i++) {
   result += String(shiftBuffer >>> 31);
   shiftBuffer <<= 1;
}
console.log(result); //"00000000000000000000000000000111"
Community
  • 1
  • 1
BairDev
  • 2,865
  • 4
  • 27
  • 50

1 Answers1

0

The important assumption here is that the initial number is less then 2^32. In that case it's just retrieving a digit after digit in binary representation.

re += String(shiftBuf >>> 31);
shiftBuf <<= 1;

The first line adds shiftBuf moved 31 places to the right to re, the second line moves shiftBuf to the left. So basically it just gets digits. Here's an example. If shiftBuf = 7; then in binary representation it is 111. Add missing zeros and you have

00000000000000000000000000000111

Step by step:

[0] shiftBuf >>> 31 produces 0  // picks first digit if shiftBuf < 2^32
[0] result is now "0"
[0] shitBuffer <<= 1 produces 00000000000000000000000000001110

[1] shiftBuf >>> 31 produces 0
[1] result is now "00"
[1] shitBuffer <<= 1 produces 00000000000000000000000000011100

[2] shiftBuf >>> 31 produces 0
[2] result is now "000"
[2] shitBuffer <<= 1 produces 00000000000000000000000000111000

...

[30] shiftBuf >>> 31 produces 1
[30] result is now "0000000000000000000000000000011"
[30] shitBuffer <<= 1 produces 10000000000000000000000000000000

[31] shiftBuf >>> 31 produces 1
[31] result is now "00000000000000000000000000000111"
[31] shitBuffer <<= 1 produces 00000000000000000000000000000000

As for your second question: the difference between these two codes is that in the first one you have for (var i = 0; i < 32; i++); (note the semicolon at the end). The code that follows (the one in brackets {}) does not run in a loop. It runs only once.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • I start to understand. So it goes from left to the right of the digital representation of the number. Shift operators always 'produce' 0 or 1? Why? Or is that the miracle of String(shiftBuf >>> 31)? – BairDev Jul 03 '14 at 11:59
  • 1
    @malte Shift operators don't always produce 0 or 1. But if we are dealing with numbers less then 2^32 (i.e. 32 digit binary number) then shifting to the right 31 times leaves us with 1 digit: 0 or 1. So if a number is bigger then 2^32 then this algorithm won't work (well it wouldn't work because of another reason: binary and shift operators only work on integers up to 2^32). – freakish Jul 03 '14 at 12:35
  • Also shifting to the left only works for integers up to 2^32. From shifting operators point of view every number is a binary number with 32 digits (with leading zeros). Shifting to the left or right does not affect number of digits (just like in my example). – freakish Jul 03 '14 at 12:49