# JavaScript Numbers

Feb 23, 2021·

### Numbers

There are basically two types of numbers in JavaScript:

• Regular numbers: These are double-precision floating-point numbers stored in 64-bit format IEEE-754. The double-precision floating-point numbers are responsible for things like imprecise calculation.
``````0.2 + 0.1 // 0.30000000000000004
// caused by double-precision floating-point (64 bit)
``````

These numbers are between -2⁵³ - 1 (minimum safe integer) and 2⁵³ - 1 (maximum safe integer).

``````Number.MIN_SAFE_INTEGER // -9007199254740991 (-2⁵³ - 1)

Number.MAX_SAFE_INTEGER // 9007199254740991 (2⁵³ - 1)
``````
• BigInt numbers: These are numbers below -2⁵³ - 1 or above 2⁵³ - 1 (B ≤ -2⁵³ - 1 or B ≥ 2⁵³ - 1)

### Numbers in underscore

Digits can be separated with underscores. For example, 18,054,020 can be represented as `18_054_020` in JavaScript.

### Numbers in exponential

Let's assume we want to represent the number 2,000,000,000 in exponential. In Maths, it's 2x10⁹. In JavaScript, it's `2e9` or `2E9`.

See the examples below:

``````2e9 === 2000000000; // true
1e-3 === 1 / 1000; // true
1.43e-6 === 1.43 / 1000000; // true
``````

In the example above, `2e-9` is the same as 0.000000002 (9 zeros to the left).

### Hex, binary and octal numbers

Hexadecimal can be used to represent colors, encode characters, etc.

Normally one or two characters (aA-fF or numbers 0 - 9) appends to `0x`.

See the example below:

``````0x4a; // 74
0xf9; // 249

console.log(`Hexadecimal numbers are between \${0x00} and \${0xff}.`)
// Hexadecimal numbers are between 0 and 255.
``````

#### Binary and octal numbers

The prefix `0b` represents a binary number while the prefix `0o` represents an octal number.

See the example below:

``````const a = 0b11111111; // binary form of 255
const b = 0o377; // octal form of 255

console.log( a === b ); // true
``````

### toString(base)

To convert a whole `num` to base `a` the syntax is:

``````num.toString(a)
``````

See the example below:

``````const num = 255;

num.toString(16);  // ff
num.toString(2);   // 11111111
``````

The base can vary from `2` to `36`. By default, it's `10`.

Note: If you do not want to use the variable (`num`) to store a number but want to call a method directly on a number, the `..` can be used.

The example above is the same as below:

``````255..toString(16);  // ff
255..toString(2);   // 11111111
``````

Alternative to the example above, it can be rewritten as shown below:

``````(255).toString(16);  // ff
(255).toString(2);   // 11111111
``````

### Rounding

There are several built-in functions for rounding:

• `Math.floor(num)` and `Math.round(num)`: They round down numbers to the nearest whole number. `3.24` becomes `3`.

The difference between `Math.floor(num)` and `Math.round(num)` is shown in the example below:

``````console.log( Math.floor(3.4), Math.round(3.4) ) // 3 3
console.log( Math.floor(3.5), Math.round(3.5) ) // 3 4
console.log( Math.floor(3.6), Math.round(3.6) ) // 3 4
``````

For negative decimal numbers (`-num`), `Math.floor(-num)` becomes `-Math.abs(num + 1)` to the nearest whole number; while `Math.round(-num)` becomes `-Math.abs(num)` to the nearest whole number.

See the example below:

``````console.log( Math.floor(-3.3), Math.round(-3.3) ); // -4 -3
``````

For positive decimal numbers, `Math.round(num)` round-up numbers (`num`) exactly at or after `.5` position but round-down numbers (`num`) before `.5` position, but `Math.floor(num)` always round-down.

• `Math.ceil(num)` always round up numbers (`num`).
``````Math.ceil(3.4) // 4
Math.ceil(3.2) // 4
Math.ceil(3.6) // 4
``````
• `Math.trunc(num)`: It is like `Math.floor` for positive numbers but like `Math.round(num)` for negative numbers.

See the example below:

``````Math.trunc(3.4); // 3
Math.trunc(3.5); // 3
Math.trunc(3.6); // 3
Math.trunc(-3.6); // 3
Math.trunc(-3.4); // 3
``````

It is advisable to use `math.trunc(num)` more often than `Math.floor(num)` to round-down numbers. `Math.floor(num)` is mostly used on positive decimal numbers.

 number Math.ceil Math.floor Math.round Math.trunc 3.1 4 3 3 3 3.6 4 3 4 3 -3.1 -3 -4 -3 -3 -3.6 -3 -4 -4 -3

`Math.trunc` is not supported by Internet Explorer

### Imprecise calculation

A number internally is represented in 64-bit format IEEE-754 - 52 bits to store digits; 11 bits to store decimal numbers position (zero for integer numbers); 1 bit for signs.

``````console.log(1e550); // Infinity
0.2 + 0.1 === 0.3 // false

// The above is false because
0.2 + 0.1 // 0.30000000000000004

// ☝ the operation on 0.1, 0.2 causes
// unending fractions in their binary form.
``````

the operation on 0.1, 0.2 causes unending fractions in their binary form

To solve the issue, we can use the method `num.toFixed(n)`

``````num.toFixed(n)
``````

See the example below:

``````const num = 0.1 + 0.2;
const result = num.toFixed(1); // 0.3

console.log(result, typeof result); // 0.3 string
console.log(typeof +result) // number
``````

`num.toFixed(n)` is in string.

`n=1` specifies the number of digits after `0.`

`toFixed` always returns a string

See the example below

``````const num = 0.2 + 0.1;
const result = num.toFixed(2);

console.log(result, typeof result); // 0.30 string
``````

To convert the result above to a number, use the unary operator (`+`) or `Number(...)`

``````const num = 0.2 + 0.1;
const result = num.toFixed(2);
const toNum = +result; // Number(result)

console.log(toNum, typeof toNum); // 0.30 number
``````

Alternatively, you can change the decimal numbers in an expression to fractional numbers and multiply both numerator and denominator by 10.

``````// const num = ((0.1 * 10) + (0.2 * 10)) / 10;
const num = ((1/10 * 10) + (2/10 * 10)) / 10;
num;
``````

The trick above doesn't always work. This means the formal, `num.toFixed(n)` is the preferred way to fix numbers.

``````0.28 + 0.14; // 0.42000000000000004

// ( (28 / 100 * 100) + (14 / 100 * 100) ) / 100
( (0.28 * 100) + (0.14 * 100) ) / 100 ; // 0.4200000000000001

// num.toFixed(n)
+(0.28 + 0.14).toFixed(2); // 0.42
``````

Integers (non-decimal) numbers are accurate up to 15 digits.

``````const a = 999999999999999;   // 15 9s
const b = 9999999999999999;  // 16 9s will lead to wrong interpretation

console.log(a, b); // 999999999999999 10000000000000000
``````

### Tests - isFinite and isNaN

• `isNaN(value)` converts its argument to a number and then tests it for being `NaN`: Non-integer values are `NaN`.

See the example below:

``````console.log( isNaN(NaN) ); // true
console.log( isNaN("str") ); // true
console.log( isNaN(10) ); // false
``````

The value NaN is unique in that it does not equal anything.

``````NaN === NaN // false
``````

In JavaScript, `Object.is(a, b)` is used when an internal algorithm needs to compare two values for being exactly the same.

``````Object.is(NaN, NaN); // true
Object.is(0, 0); // true
Object.is(0, -0); //false
``````
• `isFinite(value)` converts its argument to a number and returns true - not either `NaN` `Infinity` or `-Infinity`.

See the example below:

``````console( isFinite("41") ); // true => value number
console( isFinite("str") ); // false => value NaN
console( isFinite(Infinity) ); // false => value Infinity
``````

Sometimes `isFinite(value)` is used to validate whether a string value is a regular number:

``````const num = +prompt("Enter a number", ' ');

``````

### ParseInt and ParseFloat

• The function `parseInt(...)` returns an integer.
• The function `parseFloat(...)` returns a floating-point number.
``````parseInt(100.45) // 100
parseFloat(100) // 100.00
``````

Both functions only read a number from a string.

``````parseInt('30\$'); // 30
``````

#### ParseInt base

If a parseInt function has a second argument, the second argument becomes the base to be converted to.

See the syntax below:

``````parseInt(str[, radix])
``````
``````parseInt('0xff', 16); // 255
parseInt('ff', 16); // 255, without 0x also works

parseInt('2n9c', 36); // 123456
``````

### Built-in Math functions

Check out MDN for other built-in Math functions

Happy coding!