# Numbers and bitwise operations overview

Like other languages Javascript deals pretty well with bytes and a lot of developers tend to choose NodeJS as their favourite backend framework.

Here, I propose to review, recap some “binary” concepts about how primitive type “number” are stored, integer, float, double. It helps to understand how certain operations are performed.

I wanted to make my own visual representation of famous IEEE 754 format, so before to do that, I needed to review some basics, yes school is quite far for me too now.

Result is here : http://darul75.github.io/d3-binary-converter/

## Fact

Before digging into the ground, always fun to look at this weird result

``````  0.1 + 0.2 // 0.30000000000000004
``````

Ok, but why ? I would summarize by welcome to binary world.

## Some recaps signed vs unsigned.

For illustration, we could consider that integers are stored with only one byte (8 bits)

``````  1 binary => 0000 0001
``````
``````  -1 binary => ???? ????
``````

### One complement method

“The ones’ complement form of a negative binary number is the bitwise NOT applied to it.”

So decimal 1 number becomes -1 this way

``````  ~00000001 → 11111110
``````

Ok so let’s add 2 + (-1)

``````   0000 0010
+1111 1110
---------
1 0000 0000
``````

Result is

``````  0000 0000
``````

And not 1 as expected

``````  0000 0001
``````

### Two’s complement method

“Negating a number (whether negative or positive) is done by inverting all the bits and then adding one to that result.”

Play with 1 and try to compute -1.

``````   0000 0001
``````
• Invert all the bits through the number
``````   1111 1110
``````
``````   1111 1110
+0000 0001
---------
1111 1111
``````

Verify (-1) + 1 == 0

``````   1111 1111
0000 0001
---------
1 000000000
``````

Verify (-1) + 2 == 1

``````   1111 1111
0000 0010
---------
1 000000001
``````

Good.

Another approach consist in :

• Starting from the right, find the first ‘1’
• Invert all of the bits to the left of that one
``````1111 1111
// could be resumed like
-2^7+2^6+2^5+2^4+2^3+2^2+2^0 == -128+64+32+16+8+4+2+1
``````

## Shifting

Few recaps on shifting operators.

### « (Left shift)

“This operator shifts the first operand the specified number of bits to the left.”

``````var shift = 1;
var n = 5;  // 0000 0101

n = n << shift; // 0000 1010

// note, left shifting is equivalent to operation : n * 2^shift

n << shift == n * Math.pow(2, shift);
``````

### » (Sign-propagating right shift)

“This operator shifts the first operand the specified number of bits to the right”.

``````var shift = 1;
var n = 5;  // 0000 0101

n = n >> shift; // 0000 0010
``````

### »> (Zero-fill right shift)

“This operator shifts the first operand the specified number of bits to the right.”

Number -1 in binary format representation is:

``````  11111111111111111111111111111111
``````

What happened when you shift this number by 0 ?

``````var n = -1;  // 1111.....

n = n >>> 0; // 4294967296
``````

Surprising but not so much at the end as it will simply coerces number to unsigned one.

### Number to binary string format

Sometimes it is nice to get binary representation of a number in javascript. By looking at Mozilla API for number, you will see a nice toString([base]) method.

Let’s try using it:

``````var n = -10;  // ....1010

n.toString(2); // "-1010"
``````

“-1010” is not the real representation of your number and a better approach will be to use zero-fill right shift seen before instead.

``````
(n >>> 0).toString(2);

// 11111111111111111111111111110110 => GOOD

function dec2bin(dec){
return (dec >>> 0).toString(2);
}
``````

### ~ (Bitwise NOT)

“Yields the inverted value (a.k.a. one’s complement)”

``````var a = 3;    // 0000 0011
var notA = ~3 // 1111 1100
``````

Some of you may have seen this bunch of code somewhere.

``````var string = 'hello world, I am testing !';

if (~string.indexOf('test')) {
// do something
}

// ok weird... normaly would be something like

if (string.indexOf('test') >= 0) {
// do something
}
``````

indexOf() method return -1 in case of non matching result.

Do you remember -1 in binary representation, a nice list of bits 11111111….

Cool so if I use a NOT on -1 I get ??

``````!11111....
=> 00000....
=> 0 in decimal
=> meaning boolean false by coercion
=> false
``````

Rewrite our example a little.

``````var string = 'hello world, I am testing !';

var s1 = 'am';
var s2 = 'nothing else matters';

var containsAm = string.indexOf(s1); // === 15
var containsNothingElseMatters = string.indexOf(s2); // === -1

containsAm = ~containsAm; // -16
containsNothingElseMatters = ~containsNothingElseMatters; // 0

// so what happened when in a condition
if (containsAm) {
// ok
console.log('containsAm');
}

if (containsNothingElseMatters) {
// ok
console.log('containsNothingElseMatters');
}

// will output
// > containsAm
``````

### Boolean conversion

In previous example, what you need to remember is that in javascript:

• 0 is the same than false
• anything else is true.

You may check by using !! operator.

``````!!0; // false
!!1; // true
!!18;// true
// but also
!!-18;// true
``````

So when you see something like this in code.

``````var s = 'wtf';
// same as:  s.indexOf('tf') >= 0
if (~s.indexOf('tf')) {
console.log('now you understand what\'s going on');
}
``````

## Floating numbers IEEE 754

Our computer is just a serie of 0 and 1 isn’t it ?

And we have seen how some integer numbers (ex: 15) are normalized into a serie of bits.

But how does it work for decimal numbers ? (ex: 15.25)

A decimal number is a number that can be expressed with a fraction where denominator is a power of ten.

``````  55.25 === 5525 / 100 === 5525 / (10^2)
``````

. Ok nice but my computer does not care about power decimal and expects a binary representation instead.

Here comes IEEE 754 Binary Floating Point representation.

I won’t give all details but you can check how it works here

Javascript uses 64 bits representation precision:

• 1 bit is sign
• 11 bits exponent
• 52 bits for the fraction.

### Sign

This is the easy part, 1 bit indicates a negative number, and a 0 bit indicates a positive number.

### Mantissa

Decimal

Best way to understand how it works consist in considering decimal floating representation approach.

Replay with 55.25 number, such a number decimal floating representation would be:

``````  5,525 x 10 ^2
``````
• sign : positive
• mantissa : 5.525
• exponent: 2

The fractional portion of the mantissa is the sum of each digit multiplied by a power of 10:

``````  .525 =  5/10 + 2/100 + 5/1000
``````

Binary

A binary floating-point number is similar.

For example, in the normalized number +1,1011101 x 2^5

• the sign is positive,
• the mantissa is 1,1011101, (we don’t store first bit..)
• and the exponent is 5.

To come back to a binary representation, we shift the decimal point of mantissa by 5:

``````  1.1011101 => 110111.01
``````

Take integer/decimal parts:

``````110111 => 2^0 + 2^1 + 2^2 + 2^4 + 2^5 => 55
.01 => 2^-2 => 0.25

// result is expected number : 55.25
``````

### Exponent

IEEE Double real exponents are stored as 11-bit unsigned integers with a bias of 1023.

In previous example, exponent of 5 “biased” will become:

``````  5 + 1023 = 1028
``````

And its binary

``````  10000000100
``````

### Full representation (double precision)

``````  0 10000000100 1011101000000000000000000000000000000000000000000000
``````

Wikipedia 1 2 