# From 0 to 9: The Magic of Numbers in JavaScript

Numbers have a hidden power. Sometimes they are used in powerful forms of sorcery—just like in JavaScript. And as long you use them the right way, numbers can be a source of lot of fun in learning JS.

🤓 **Note:** I'm going to use ES2015 in the following examples. Not all will work

natively everywhere (you need a ES2015 supported interpreter, but don't worry probably you don't have to take care of that; you probably have it already).

*Some of the examples are ES2015 specific. In that case, there is a specific note.*

So, let's go!

## Learning JavaScript by the Numbers—from 0 to 9

## 0. Zero-based things

Like in other programming languages, array indexes are zero-based. You start counting with zero; why is this so?

**First**: Whoops, I'll try again.

**Zero**: It's about saving space. The elements from any array are stored somewhere in the memory.

Imagine the memory looks like this:

```
Memory: _ _ _ _ _ _ _ _ _ _ _ _ _
Data: [A, B, C]
^ First index
```

Now, let's assume the array is located in memory at location *X*. In zero-based indexing, to access the element at index `i`

(by using `array[i]`

), the computer has to: *get me the content at location X + i* (e.g. for

`i = 0`

, `array[X + 0]`

will be the first element).In case we want one-based indexing, we lose one position in the memory buffer:

```
Memory: _ _ _ _ _ _ _ _ _ _ _ _ _
Data: [ A, B, C]
^ First index
^ Unused memory gap
```

So the location *X* is now not used at all, while the next ones are used. If you want to use it, then you need to do a subtraction (*get me content at X + i - 1*), which is explained in the next point.

**First**: It's about optimizing things. Starting the count from zero is more efficient.

Let's take an example:

```
let fruits = ["Apples", "Pears", "Oranges"];
// Indexes: 0 1 2
```

The length of the array is `3`

(there are three elements). We can say that any index number is matching in the following math expression:

```
0 ≤ index < 3
0 ≤ 0 < 3 → true
0 ≤ 1 < 3 → true
0 ≤ 2 < 3 → true
```

Now let's see what would happen if we have a one-based indexing:

```
let fruits = ["Apples", "Pears", "Oranges"];
// Indexes: 1 2 3
let N = fruits.length;
1 ≤ index < N + 1
1 ≤ 1 < 4
1 ≤ 2 < 4
1 ≤ 3 < 4
```

You may think now: well, what's the issue here? The problem is when we do `N + 1`

. It's a bit of unnecessary extra work for the computer.

**Second**: `1`

is the smallest integer which is still a valid value for a non-empty array length.

🤓 **Note**: The months in JavaScript dates are also zero-based (0-11). If you want to get the *first of January 2016*, you want to do:

```
console.log(new Date(2016, 0, 1).toString())
→ Fri Jan 01 2016 00:00:00 GMT+0200 (EET)
```

Could that be because months have labels attached with the indexes, so it's faster to access them internally (like I mentioned above)? Maybe!

## 1. Representing numbers and working with them

There are many ways to represent numbers in JavaScript. Here are a few of them. In some cases, the syntax looks weird and even though it's a valid syntax, you probably won't use it. But it's good to know that such cases are possible.

#### Integers

```
> 42
42
// The dot is displayed only if there are non-zero digits after the dot
> 42.000
42
```

#### Floating point

```
> 3.14
3.14
```

#### Octals (aka base 8)

Octals use a leading `0`

:

```
> 0123
83
```

Note the above format is forbidden in ES5 strict mode. In ES6, we can use `0o...`

:

```
> 0o123
83
```

#### Hex (aka base 16)

```
> 0xFF
255
> parseInt("0xFF", 16)
255
```

#### Exponent

`eX`

is an abbreviation for *multiply with 10ˣ*.

```
> 7e3
7000
```

Explanation:

```
7 * 10 * 10 * 10
\__________/
7 * (1)e3
7 * 1000
7000
```

💡 **Tip**: It works nicely with negative exponents:

```
> 7e-2
0.07
```

#### Binary (added in ES2015+)

It starts with `0b`

, followed by the binary snippet (`1`

and `0`

digits).

```
> 0b1101
13
```

#### Playing with the dot:

```
> 42.
42
```

For values lower than 0, you can start directly with the dot:

```
> .42
0.42
```

💡 **Tip**: This works in CSS as well:

```
div.myElement {
opacity: .5;
}
```

`Number`

constructor

2. Playing with the All the numbers above have the `Number`

constructor:

```
> a = 42
42
> a.constructor
[Function: Number]
> typeof a
"number"
```

So, obviously they are *numbers*. But one thing we should remember is that in JavaScript, everything is an object. So, are numbers objects in JavaScript? Of course!

A simple proof is by adding a new method to the `Number`

prototype:

```
Number.prototype.me = function () {
return this;
};
// Let's create a variable
let foo = 42;
// Obviously, it's a number
typeof foo;
// → "number"
// But let's use the `me` method which we added
// (it returns the Number instance)
typeof foo.me();
// → "object"
// And of course it can be used in operations
foo.me() + 1;
// → 43
```

We can create such numbers using `new Number(...)`

.

```
let a = new Number(42);
typeof a;
// → "object"
a + 1;
// → 43
// Note, by outputting this, we get an object:
console.log(a);
// → [Number: 42]
// Calling the valueOf will return the real number
console.log(a.valueOf());
// → 42
```

Is this actually useful for anything? Well, yes!

The `Number`

constructor can be used without `new`

as well. It will convert the things into numbers (read more about this here):

```
let str = "\n\n42\t\n";
let foo = Number(str);
console.log(foo);
// → 42
```

Putting these two things together, we can create our own object, and return set a custom conversion when we use it in Number operations:

```
let magicObject = {
foo: 42
, hello: "world"
// This will return the numeric value
, valueOf () {
return this.foo;
}
};
// Let's convert it into a number
console.log(+magicObject);
// → 43
console.log(-magicObject);
// → -43
// Add 1 to the sum
console.log(magicObject + 1);
// → 43
// Additionally, you can set a custom stringify function:
magicObject.toString = function () { return this.hello; };
console.log(`Hello ${magicObject}!`);
// → "Hello world!"
```

## 3. Invoking methods on number literals

The following syntax is strange, but still valid:

```
> .42.toString()
"0.42"
> 0.42.toString()
"0.42"
```

💡 **Tip:** It's a good practice to use wrapping parentheses around such numbers, and here's why:

```
> (0.42).toString()
"0.42"
> (.42).toString()
"0.42"
> .42.toString()
"0.42"
> 0.42.toString()
"0.42"
// Note this: we do call the toString() function,
// but get a number in the end
> -0.42.toString()
-0.42
// When adding the wrapping parentheses, it's working fine
> (-0.42).toString()
'-0.42'
// But if we take the operator outside of the parentheses,
// we do get a number
> -(0.42).toString()
-0.42
```

If you use an arithmetic operator there (generally `-`

), you need to wrap it, too.

Otherwise, you'll get a number in the end. This is because of the operations order:

```
-0.42.toString()
// \_____________/
// - '0.42'
// -0.42
```

When you wrap your numbers between parentheses, you simply convert the (negative) number into a string.

`===`

!== `==`

(AKA strict equal)

4. Strictly use strict equal! As mentioned in this article, it's definitely better to use strict equal.

If you know a bit of JavaScript, this is one of the

first things you learn. In most popular programming languages, to check if something equals something else, you're going to have to use `==`

:

```
// Assign the value
let foo = 42;
// Check if `foo` is 42
foo === 42
// → true
```

In JavaScript, this works but it does something else. It's a *liberal equal*, if you like to call it so:

```
"42" == 42
// → true
// Add some spaces, new lines and tabs in that string
"\n\t 42 \t\n\n" == 42
// → true
```

Using `===`

(strict equal) definitely makes a change:

```
"42" === 42
// → false
```

## 5. Special numbers

There are quite a few special numbers:

`-0`

—negative zero (usually we use the positive value:`+0`

or just`0`

)`NaN`

(not a number)`Infinity`

and`-Infinity`

In the `Number`

object you will find quite a few other constants:

```
// The largest representable number
> Number.MAX_VALUE
1.7976931348623157e+308
// The smallest representable number
> Number.MIN_VALUE
5e-324
// Special "not a number" value
> Number.NaN
NaN
// Special negative infinite value; returned on overflow
> Number.NEGATIVE_INFINITY
-Infinity
// Special positive infinite value; returned on overflow
> Number.POSITIVE_INFINITY
Infinity
// Difference between one and the smallest value greater
// than one that can be represented as a Number.
> Number.EPSILON
2.220446049250313e-16
// Minimum safe integer in JavaScript.
> Number.MIN_SAFE_INTEGER
-9007199254740991
// Maximum safe integer in JavaScript.
> Number.MAX_SAFE_INTEGER
9007199254740991
```

Also, there are few constants in the `Math`

object (e.g. `Math.PI`

, `Math.E`

etc).

`-0`

6. Catching Note that `-0 === +0`

is `true`

. But still, they are doing totally different things:

```
> 42 / 0
Infinity
> 42 / -0
-Infinity
```

So, if you ever have to check if it's a negative zero, you can simply make such a division and see what you get.

## 7. Weird results and expressions

As mentioned above, we do get (negative) `Infinity`

values when dividing most of the numbers to (negative) zero.

But still, there are few other cases when we get interesting results:

```
// Dividing zero by zero
0 / 0
→ NaN
// Note there is no -NaN
0 / -0
→ NaN
```

A rather nice one is 0⁰ which should be mathematically impossible—at least that's what they teach us in school. Well, JavaScript says it's 1, and that's dictated by specs (if the exponent is `0`

, the result is `1`

always).

```
Math.pow(0, 0)
→ 1
Math.pow(NaN, 0);
→ 1
```

Infinity plus anything is still infinity:

```
Infinity + 42
→ Infinity
Infinity + Infinity
→ Infinity
```

Though, you get a `NaN`

if you subtract `Infinity`

from itself:

```
Infinity - Infinity
→ NaN
```

You may be surprised that in JavaScript, `0.1 + 0.2 === 0.3`

is false:

```
0.1 + 0.2 === 0.3
// → false
```

##### What's going on here?!

Well, it is due to errors in the floating point precision. Let's take a closer look:

```
> 0.1 + 0.2
0.30000000000000004
> 0.1 * 0.2
0.020000000000000004
```

But why is this happening?! It's because of the way computers represent the numbers internally. The short explanation would be: when you divide 1 / 3, you probably round it to `0.333...`

. But if you're going to sum `0.333...`

three times, you will get `0.999...`

instead of `1`

(note in this case `...`

doesn't represent an infinite series of decimals, but just your precision; btw, `X.999999...`

—an infinite series of `9`

—does equal `X + 1`

in the real world).

So, it's just because of precision. You'll find better and longer explanations here; and how to solve such problems.

`null`

equal zero?

Does You'd say *no*: `null === 0 → false`

, but let's look at this:

```
> null < 0
false
> null <= 0
true
> null === 0
false
> null == 0
false
> null >= 0
true
> null > 0
false
```

So, **what's going on here**, again?! Well, it's JavaScript.

As first hint, we can check how is `null`

converted into a number: `+null`

→ `0`

. Since `null`

converted to a number is `0`

, the expressions above make sense—except the strict equal one. The explanation is easy: all the others call the `ToPrimitive`

operation with a `Number`

as preferred type.

`NaN`

(not a number) thingy

8. The `NaN`

obviously means *not a number*. Ironically, `NaN`

*is* a number (well, it has the `number`

type):

```
typeof NaN // "number"
NaN.constructor // Number
```

There are multiple ways to assign `NaN`

to a variable:

```
// Just by using the `NaN` value
let foo = NaN; // NaN
// By parsing a non-number as number
parseInt("foo") // NaN
// Or shorter:
+'foo' // NaN
```

`x !== x`

Sometimes Because IEEE 754 dictates that `NaN !== NaN`

, there we are:

```
NaN !== NaN
→ true
```

That's the reason why you should *never* check if `foo`

is a *not a number* by checking if `foo === NaN`

but by checking if `foo !== foo`

or `isNaN(foo)`

.

**Do you want to create another similar value by doing the same thing?**

Well, we can try something that's almost the same. Let's do it:

```
// Let's define a property having a getter which returns a random number always
Object.defineProperty(this, "foo", {
get () { return Math.random(); }
});
foo
→ 0.5300470317035524
foo
→ 0.4810690031991778
...
// Now, of course that:
foo !== foo
→ true
```

However, if you create a variable and assign the `foo`

's value to it, then it won't work anymore (but it does work with `NaN`

):

```
> a = foo
0.2264466197115489
> a === a
true
> a = NaN
NaN
> a === a
false
```

## 9. The power of bitwise operators

There are quite a few amazing things you can do with the low level operators which modify the bits of the numbers.

#### Fast multiplications/divisions

Do you want to multiply/divide a number with powers of 2 (2, 4, 8, 16 etc)? Do you want to make it extremely fast? Then, the answer is to use the `<<`

operator:

```
// Same with 3 * 2, but faster
> 3 << 1
6
// Same with 3 * 4
> 3 << 2
12
// Same with 3 * 8
> 3 << 3
24
// Divide by two
> 16 >> 1
8
```

What happens is that `<<`

moves all the bits to the left one position. Since the numbers are represented in binary, it adds a new `0`

on the right side:

```
// 5 in base 2:
101
101 << 1
→ 1010 (which is 10 in base 2)
```

Similar things happen when using the `>>`

operator.

From my testing, using this `<<`

is about `1.04`

times faster than using the `*`

operator. Maybe it makes sense when you really care about performance (e.g. rendering some complicated 3D animations).

📝 **Note**: This doesn't work for non-integers.

#### Checking if an element is included into an array

Using the `~`

(bitwise NOT) bitwise operator to find if an element is included into an array:

```
let myArray = [1, 2, 42];
if (~myArray.indexOf(42)) {
/* do something */
}
```

What happens is that there is `indexOf`

that returns the index of the element (in this case, `2`

), or `-1`

if the element doesn't exist. `-1`

is the only number for which `~`

will return `0`

. `~`

turns `0`

into `1`

and `1`

into `0`

at bit level.

```
~-1
→ 0
~0
→ 0
~42
→ -43
~-42
~41
```

Then, obviously, `0`

is a false value when converted to boolean, while the other numbers returned by `~`

are truly values. So, we can do something like this:

```
let myArray = [4, 3, 42, 1];
// Get the index:
myArray.indexOf(42)
// → 2
// Let's check if it exists (convert to boolean)
!!~myArray.indexOf(42)
→ true
// ... and one which doesn't exist:
!!~myArray.indexOf(7)
→ false
```

#### Cryptography fun

The XOR (`^`

) operator is really cute. You can encrypt and decrypt messages using it. Here is how it works:

```
A B ^
=========
0 0 0
0 1 1
1 0 1
1 1 0
```

This is used in cryptography. A simple example would be encrypting and decrypting a number:

```
// Alice and Bob know the same secret key:
let key = 42;
// Alice wants to send Bob a number
let msg = 7;
// But before sending it, Alice encrypts it:
msg = msg ^ key // or directly: msg ^= key
→ 45
// Bob receives 45, but knowing the key is 42 he knows to decrypt it:
45 ^ key
→ 7
// Now Bob can enjoy the message from Alice
```

## Wrapping up

Hopefully you enjoyed this read and you learned something! Have fun using numbers for the good of this world. 🚀