JavaScript for impatient programmers (ES2022 edition)

## 16 Numbers

JavaScript has two kinds of numeric values:

• Numbers are 64-bit floating point numbers and are also used for smaller integers (within a range of plus/minus 53 bits).
• Bigints represent integers with an arbitrary precision.

This chapter covers numbers. Bigints are covered later in this book.

### 16.1 Numbers are used for both floating point numbers and integers

The type `number` is used for both integers and floating point numbers in JavaScript:

``````98
123.45``````

However, all numbers are doubles, 64-bit floating point numbers implemented according to the IEEE Standard for Floating-Point Arithmetic (IEEE 754).

Integer numbers are simply floating point numbers without a decimal fraction:

``````> 98 === 98.0
true``````

Note that, under the hood, most JavaScript engines are often able to use real integers, with all associated performance and storage size benefits.

### 16.2 Number literals

Let’s examine literals for numbers.

#### 16.2.1 Integer literals

Several integer literals let us express integers with various bases:

``````// Binary (base 2)
assert.equal(0b11, 3); // ES6

// Octal (base 8)
assert.equal(0o10, 8); // ES6

// Decimal (base 10)
assert.equal(35, 35);

assert.equal(0xE7, 231);``````

#### 16.2.2 Floating point literals

Floating point numbers can only be expressed in base 10.

Fractions:

``````> 35.0
35``````

Exponent: `eN` means ×10N

``````> 3e2
300
> 3e-2
0.03
> 0.3e2
30``````

#### 16.2.3 Syntactic pitfall: properties of integer literals

Accessing a property of an integer literal entails a pitfall: If the integer literal is immediately followed by a dot, then that dot is interpreted as a decimal dot:

``7.toString(); // syntax error``

There are four ways to work around this pitfall:

``````7.0.toString()
(7).toString()
7..toString()
7 .toString()  // space before dot``````

#### 16.2.4 Underscores (`_`) as separators in number literals [ES2021]

Grouping digits to make long numbers more readable has a long tradition. For example:

• In 1825, London had 1,335,000 inhabitants.
• The distance between Earth and Sun is 149,600,000 km.

Since ES2021, we can use underscores as separators in number literals:

``````const inhabitantsOfLondon = 1_335_000;
const distanceEarthSunInKm = 149_600_000;``````

With other bases, grouping is important, too:

``````const fileSystemPermission = 0b111_111_000;
const bytes = 0b1111_10101011_11110000_00001101;
const words = 0xFAB_F00D;``````

We can also use the separator in fractions and exponents:

``````const massOfElectronInKg = 9.109_383_56e-31;
const trillionInShortScale = 1e1_2;``````
##### 16.2.4.1 Where can we put separators?

The locations of separators are restricted in two ways:

• We can only put underscores between two digits. Therefore, all of the following number literals are illegal:

``````3_.141
3._141

1_e12
1e_12

_1464301  // valid variable name!
1464301_

0_b111111000
0b_111111000``````
• We can’t use more than one underscore in a row:

``123__456 // two underscores – not allowed``

The motivation behind these restrictions is to keep parsing simple and to avoid strange edge cases.

##### 16.2.4.2 Parsing numbers with separators

The following functions for parsing numbers do not support separators:

• `Number()`
• `Number.parseInt()`
• `Number.parseFloat()`

For example:

``````> Number('123_456')
NaN
> Number.parseInt('123_456')
123``````

The rationale is that numeric separators are for code. Other kinds of input should be processed differently.

### 16.3 Arithmetic operators

#### 16.3.1 Binary arithmetic operators

Tbl. 5 lists JavaScript’s binary arithmetic operators.

Table 5: Binary arithmetic operators.
Operator Name Example
`n + m` Addition ES1 `3 + 4` `→` `7`
`n - m` Subtraction ES1 `9 - 1` `→` `8`
`n * m` Multiplication ES1 `3 * 2.25` `→` `6.75`
`n / m` Division ES1 `5.625 / 5` `→` `1.125`
`n % m` Remainder ES1 `8 % 5` `→` `3`
`-8 % 5` `→` `-3`
`n ** m` Exponentiation ES2016 `4 ** 2` `→` `16`
##### 16.3.1.1 `%` is a remainder operator

`%` is a remainder operator, not a modulo operator. Its result has the sign of the first operand:

``````> 5 % 3
2
> -5 % 3
-2``````

For more information on the difference between remainder and modulo, see the blog post “Remainder operator vs. modulo operator (with JavaScript code)” on 2ality.

#### 16.3.2 Unary plus (`+`) and negation (`-`)

Tbl. 6 summarizes the two operators unary plus (`+`) and negation (`-`).

Table 6: The operators unary plus (`+`) and negation (`-`).
Operator Name Example
`+n` Unary plus ES1 `+(-7)` `→` `-7`
`-n` Unary negation ES1 `-(-7)` `→` `7`

Both operators coerce their operands to numbers:

``````> +'5'
5
> +'-12'
-12
> -'9'
-9``````

Thus, unary plus lets us convert arbitrary values to numbers.

#### 16.3.3 Incrementing (`++`) and decrementing (`--`)

The incrementation operator `++` exists in a prefix version and a suffix version. In both versions, it destructively adds one to its operand. Therefore, its operand must be a storage location that can be changed.

The decrementation operator `--` works the same, but subtracts one from its operand. The next two examples explain the difference between the prefix and the suffix version.

Tbl. 7 summarizes the incrementation and decrementation operators.

Table 7: Incrementation operators and decrementation operators.
Operator Name Example
`v++` Increment ES1 `let v=0; [v++, v]` `→` `[0, 1]`
`++v` Increment ES1 `let v=0; [++v, v]` `→` `[1, 1]`
`v--` Decrement ES1 `let v=1; [v--, v]` `→` `[1, 0]`
`--v` Decrement ES1 `let v=1; [--v, v]` `→` `[0, 0]`

Next, we’ll look at examples of these operators in use.

Prefix `++` and prefix `--` change their operands and then return them.

``````let foo = 3;
assert.equal(++foo, 4);
assert.equal(foo, 4);

let bar = 3;
assert.equal(--bar, 2);
assert.equal(bar, 2);``````

Suffix `++` and suffix `--` return their operands and then change them.

``````let foo = 3;
assert.equal(foo++, 3);
assert.equal(foo, 4);

let bar = 3;
assert.equal(bar--, 3);
assert.equal(bar, 2);``````
##### 16.3.3.1 Operands: not just variables

We can also apply these operators to property values:

``````const obj = { a: 1 };
++obj.a;
assert.equal(obj.a, 2);``````

And to Array elements:

``````const arr = [ 4 ];
arr++;
assert.deepEqual(arr, );`````` Exercise: Number operators

`exercises/numbers-math/is_odd_test.mjs`

### 16.4 Converting to number

These are three ways of converting values to numbers:

• `Number(value)`
• `+value`
• `parseFloat(value)` (avoid; different than the other two!)

Recommendation: use the descriptive `Number()`. Tbl. 8 summarizes how it works.

Table 8: Converting values to numbers.
`x` `Number(x)`
`undefined` `NaN`
`null` `0`
boolean `false` `→` `0`, `true` `→` `1`
number `x` (no change)
bigint `-1n` `→` `-1`, `1n` `→` `1`, etc.
string `''` `→` `0`
Other `→` parsed number, ignoring leading/trailing whitespace
symbol Throws `TypeError`
object Configurable (e.g. via `.valueOf()`)

Examples:

``````assert.equal(Number(123.45), 123.45);

assert.equal(Number(''), 0);
assert.equal(Number('\n 123.45 \t'), 123.45);
assert.equal(Number('xyz'), NaN);

assert.equal(Number(-123n), -123);``````

How objects are converted to numbers can be configured – for example, by overriding `.valueOf()`:

``````> Number({ valueOf() { return 123 } })
123`````` Exercise: Converting to number

`exercises/numbers-math/parse_number_test.mjs`

### 16.5 Error values

Two number values are returned when errors happen:

• `NaN`
• `Infinity`

#### 16.5.1 Error value: `NaN`

`NaN` is an abbreviation of “not a number”. Ironically, JavaScript considers it to be a number:

``````> typeof NaN
'number'``````

When is `NaN` returned?

`NaN` is returned if a number can’t be parsed:

``````> Number('\$\$\$')
NaN
> Number(undefined)
NaN``````

`NaN` is returned if an operation can’t be performed:

``````> Math.log(-1)
NaN
> Math.sqrt(-1)
NaN``````

`NaN` is returned if an operand or argument is `NaN` (to propagate errors):

``````> NaN - 3
NaN
> 7 ** NaN
NaN``````
##### 16.5.1.1 Checking for `NaN`

`NaN` is the only JavaScript value that is not strictly equal to itself:

``````const n = NaN;
assert.equal(n === n, false);``````

These are several ways of checking if a value `x` is `NaN`:

``````const x = NaN;

assert.equal(Number.isNaN(x), true); // preferred
assert.equal(Object.is(x, NaN), true);
assert.equal(x !== x, true);``````

In the last line, we use the comparison quirk to detect `NaN`.

##### 16.5.1.2 Finding `NaN` in Arrays

Some Array methods can’t find `NaN`:

``````> [NaN].indexOf(NaN)
-1``````

Others can:

``````> [NaN].includes(NaN)
true
> [NaN].findIndex(x => Number.isNaN(x))
0
> [NaN].find(x => Number.isNaN(x))
NaN``````

Alas, there is no simple rule of thumb. We have to check for each method how it handles `NaN`.

#### 16.5.2 Error value: `Infinity`

When is the error value `Infinity` returned?

Infinity is returned if a number is too large:

``````> Math.pow(2, 1023)
8.98846567431158e+307
> Math.pow(2, 1024)
Infinity``````

Infinity is returned if there is a division by zero:

``````> 5 / 0
Infinity
> -5 / 0
-Infinity``````
##### 16.5.2.1 `Infinity` as a default value

`Infinity` is larger than all other numbers (except `NaN`), making it a good default value:

``````function findMinimum(numbers) {
let min = Infinity;
for (const n of numbers) {
if (n < min) min = n;
}
return min;
}

assert.equal(findMinimum([5, -1, 2]), -1);
assert.equal(findMinimum([]), Infinity);``````
##### 16.5.2.2 Checking for `Infinity`

These are two common ways of checking if a value `x` is `Infinity`:

``````const x = Infinity;

assert.equal(x === Infinity, true);
assert.equal(Number.isFinite(x), false);`````` Exercise: Comparing numbers

`exercises/numbers-math/find_max_test.mjs`

### 16.6 The precision of numbers: careful with decimal fractions

Internally, JavaScript floating point numbers are represented with base 2 (according to the IEEE 754 standard). That means that decimal fractions (base 10) can’t always be represented precisely:

``````> 0.1 + 0.2
0.30000000000000004
> 1.3 * 3
3.9000000000000004
> 1.4 * 100000000000000
139999999999999.98``````

We therefore need to take rounding errors into consideration when performing arithmetic in JavaScript.

Read on for an explanation of this phenomenon. Quiz: basic

See quiz app.

All remaining sections of this chapter are advanced.

### 16.8 Background: floating point precision

In JavaScript, computations with numbers don’t always produce correct results – for example:

``````> 0.1 + 0.2
0.30000000000000004``````

To understand why, we need to explore how JavaScript represents floating point numbers internally. It uses three integers to do so, which take up a total of 64 bits of storage (double precision):

Component Size Integer range
Sign 1 bit [0, 1]
Fraction 52 bits [0, 252−1]
Exponent 11 bits [−1023, 1024]

The floating point number represented by these integers is computed as follows:

(–1)sign × 0b1.fraction × 2exponent

This representation can’t encode a zero because its second component (involving the fraction) always has a leading 1. Therefore, a zero is encoded via the special exponent −1023 and a fraction 0.

#### 16.8.1 A simplified representation of floating point numbers

To make further discussions easier, we simplify the previous representation:

• Instead of base 2 (binary), we use base 10 (decimal) because that’s what most people are more familiar with.
• The fraction is a natural number that is interpreted as a fraction (digits after a point). We switch to a mantissa, an integer that is interpreted as itself. As a consequence, the exponent is used differently, but its fundamental role doesn’t change.
• As the mantissa is an integer (with its own sign), we don’t need a separate sign, anymore.

The new representation works like this:

mantissa × 10exponent

Let’s try out this representation for a few floating point numbers.

• For the integer −123, we mainly need the mantissa:

``````> -123 * (10 ** 0)
-123``````
• For the number 1.5, we imagine there being a point after the mantissa. We use a negative exponent to move that point one digit to the left:

``````> 15 * (10 ** -1)
1.5``````
• For the number 0.25, we move the point two digits to the left:

``````> 25 * (10 ** -2)
0.25``````

Representations with negative exponents can also be written as fractions with positive exponents in the denominators:

``````> 15 * (10 ** -1) === 15 / (10 ** 1)
true
> 25 * (10 ** -2) === 25 / (10 ** 2)
true``````

These fractions help with understanding why there are numbers that our encoding cannot represent:

• `1/10` can be represented. It already has the required format: a power of 10 in the denominator.

• `1/2` can be represented as `5/10`. We turned the 2 in the denominator into a power of 10 by multiplying the numerator and denominator by 5.

• `1/4` can be represented as `25/100`. We turned the 4 in the denominator into a power of 10 by multiplying the numerator and denominator by 25.

• `1/3` cannot be represented. There is no way to turn the denominator into a power of 10. (The prime factors of 10 are 2 and 5. Therefore, any denominator that only has these prime factors can be converted to a power of 10, by multiplying both the numerator and denominator by enough twos and fives. If a denominator has a different prime factor, then there’s nothing we can do.)

To conclude our excursion, we switch back to base 2:

• `0.5 = 1/2` can be represented with base 2 because the denominator is already a power of 2.
• `0.25 = 1/4` can be represented with base 2 because the denominator is already a power of 2.
• `0.1 = 1/10` cannot be represented because the denominator cannot be converted to a power of 2.
• `0.2 = 2/10` cannot be represented because the denominator cannot be converted to a power of 2.

Now we can see why `0.1 + 0.2` doesn’t produce a correct result: internally, neither of the two operands can be represented precisely.

The only way to compute precisely with decimal fractions is by internally switching to base 10. For many programming languages, base 2 is the default and base 10 an option. For example, Java has the class `BigDecimal` and Python has the module `decimal`. There are plans to add something similar to JavaScript: the ECMAScript proposal “Decimal”.

### 16.9 Integer numbers in JavaScript

Integer numbers are normal (floating point) numbers without decimal fractions:

``````> 1 === 1.0
true
> Number.isInteger(1.0)
true``````

In this section, we’ll look at a few tools for working with these pseudo-integers. JavaScript also supports bigints, which are real integers.

#### 16.9.1 Converting to integer

The recommended way of converting numbers to integers is to use one of the rounding methods of the `Math` object:

• `Math.floor(n)`: returns the largest integer `i``n`

``````> Math.floor(2.1)
2
> Math.floor(2.9)
2``````
• `Math.ceil(n)`: returns the smallest integer `i``n`

``````> Math.ceil(2.1)
3
> Math.ceil(2.9)
3``````
• `Math.round(n)`: returns the integer that is “closest” to `n` with `__.5` being rounded up – for example:

``````> Math.round(2.4)
2
> Math.round(2.5)
3``````
• `Math.trunc(n)`: removes any decimal fraction (after the point) that `n` has, therefore turning it into an integer.

``````> Math.trunc(2.1)
2
> Math.trunc(2.9)
2``````

#### 16.9.2 Ranges of integer numbers in JavaScript

These are important ranges of integer numbers in JavaScript:

• Safe integers: can be represented “safely” by JavaScript (more on what that means in the next subsection)
• Precision: 53 bits plus sign
• Range: (−253, 253)
• Array indices
• Precision: 32 bits, unsigned
• Range: [0, 232−1) (excluding the maximum length)
• Typed Arrays have a larger range of 53 bits (safe and unsigned)
• Bitwise operators (bitwise Or, etc.)
• Precision: 32 bits
• Range of unsigned right shift (`>>>`): unsigned, [0, 232)
• Range of all other bitwise operators: signed, [−231, 231)

#### 16.9.3 Safe integers

This is the range of integer numbers that are safe in JavaScript (53 bits plus a sign):

[–(253)+1, 253–1]

An integer is safe if it is represented by exactly one JavaScript number. Given that JavaScript numbers are encoded as a fraction multiplied by 2 to the power of an exponent, higher integers can also be represented, but then there are gaps between them.

For example (18014398509481984 is 254):

``````> 18014398509481984
18014398509481984
> 18014398509481985
18014398509481984
> 18014398509481986
18014398509481984
> 18014398509481987
18014398509481988``````

The following properties of `Number` help determine if an integer is safe:

``````assert.equal(Number.MAX_SAFE_INTEGER, (2 ** 53) - 1);
assert.equal(Number.MIN_SAFE_INTEGER, -Number.MAX_SAFE_INTEGER);

assert.equal(Number.isSafeInteger(5), true);
assert.equal(Number.isSafeInteger('5'), false);
assert.equal(Number.isSafeInteger(5.1), false);
assert.equal(Number.isSafeInteger(Number.MAX_SAFE_INTEGER), true);
assert.equal(Number.isSafeInteger(Number.MAX_SAFE_INTEGER+1), false);`````` Exercise: Detecting safe integers

`exercises/numbers-math/is_safe_integer_test.mjs`

##### 16.9.3.1 Safe computations

Let’s look at computations involving unsafe integers.

The following result is incorrect and unsafe, even though both of its operands are safe:

``````> 9007199254740990 + 3
9007199254740992``````

The following result is safe, but incorrect. The first operand is unsafe; the second operand is safe:

``````> 9007199254740995 - 10
9007199254740986``````

Therefore, the result of an expression `a op b` is correct if and only if:

``isSafeInteger(a) && isSafeInteger(b) && isSafeInteger(a op b)``

That is, both operands and the result must be safe.

### 16.10 Bitwise operators

#### 16.10.1 Internally, bitwise operators work with 32-bit integers

Internally, JavaScript’s bitwise operators work with 32-bit integers. They produce their results in the following steps:

• Input (JavaScript numbers): The 1–2 operands are first converted to JavaScript numbers (64-bit floating point numbers) and then to 32-bit integers.
• Computation (32-bit integers): The actual operation processes 32-bit integers and produces a 32-bit integer.
• Output (JavaScript number): Before returning the result, it is converted back to a JavaScript number.
##### 16.10.1.1 The types of operands and results

For each bitwise operator, this book mentions the types of its operands and its result. Each type is always one of the following two:

Type Description Size Range
Int32 signed 32-bit integer 32 bits incl. sign [−231, 231)
Uint32 unsigned 32-bit integer 32 bits [0, 232)

Considering the previously mentioned steps, I recommend to pretend that bitwise operators internally work with unsigned 32-bit integers (step “computation”) and that Int32 and Uint32 only affect how JavaScript numbers are converted to and from integers (steps “input” and “output”).

##### 16.10.1.2 Displaying JavaScript numbers as unsigned 32-bit integers

While exploring the bitwise operators, it occasionally helps to display JavaScript numbers as unsigned 32-bit integers in binary notation. That’s what `b32()` does (whose implementation is shown later):

``````assert.equal(
b32(-1),
'11111111111111111111111111111111');
assert.equal(
b32(1),
'00000000000000000000000000000001');
assert.equal(
b32(2 ** 31),
'10000000000000000000000000000000');``````

#### 16.10.2 Bitwise Not

Table 9: The bitwise Not operator.
Operation Name Type signature
`~num` Bitwise Not, ones’ complement Int32 `→` Int32 ES1

The bitwise Not operator (tbl. 9) inverts each binary digit of its operand:

``````> b32(~0b100)
'11111111111111111111111111111011'``````

This so-called ones’ complement is similar to a negative for some arithmetic operations. For example, adding an integer to its ones’ complement is always `-1`:

``````> 4 + ~4
-1
> -11 + ~-11
-1``````

#### 16.10.3 Binary bitwise operators

Table 10: Binary bitwise operators.
Operation Name Type signature
`num1 & num2` Bitwise And Int32 × Int32 `→` Int32 ES1
`num1 ¦ num2` Bitwise Or Int32 × Int32 `→` Int32 ES1
`num1 ^ num2` Bitwise Xor Int32 × Int32 `→` Int32 ES1

The binary bitwise operators (tbl. 10) combine the bits of their operands to produce their results:

``````> (0b1010 & 0b0011).toString(2).padStart(4, '0')
'0010'
'1011'
'1001'``````

#### 16.10.4 Bitwise shift operators

Table 11: Bitwise shift operators.
Operation Name Type signature
`num << count` Left shift Int32 × Uint32 `→` Int32 ES1
`num >> count` Signed right shift Int32 × Uint32 `→` Int32 ES1
`num >>> count` Unsigned right shift Uint32 × Uint32 `→` Uint32 ES1

The shift operators (tbl. 11) move binary digits to the left or to the right:

``````> (0b10 << 1).toString(2)
'100'``````

`>>` preserves highest bit, `>>>` doesn’t:

``````> b32(0b10000000000000000000000000000010 >> 1)
'11000000000000000000000000000001'
> b32(0b10000000000000000000000000000010 >>> 1)
'01000000000000000000000000000001'``````

#### 16.10.5 `b32()`: displaying unsigned 32-bit integers in binary notation

We have now used `b32()` a few times. The following code is an implementation of it:

``````/**
* Return a string representing n as a 32-bit unsigned integer,
* in binary notation.
*/
function b32(n) {
// >>> ensures highest bit isn’t interpreted as a sign
}
assert.equal(
b32(6),
'00000000000000000000000000000110');``````

`n >>> 0` means that we are shifting `n` zero bits to the right. Therefore, in principle, the `>>>` operator does nothing, but it still coerces `n` to an unsigned 32-bit integer:

``````> 12 >>> 0
12
> -12 >>> 0
4294967284
> (2**32 + 1) >>> 0
1``````

### 16.11 Quick reference: numbers

#### 16.11.1 Global functions for numbers

JavaScript has the following four global functions for numbers:

• `isFinite()`
• `isNaN()`
• `parseFloat()`
• `parseInt()`

However, it is better to use the corresponding methods of `Number` (`Number.isFinite()`, etc.), which have fewer pitfalls. They were introduced with ES6 and are discussed below.

#### 16.11.2 Static properties of `Number`

• `.EPSILON: number` [ES6]

The difference between 1 and the next representable floating point number. In general, a machine epsilon provides an upper bound for rounding errors in floating point arithmetic.

• Approximately: 2.2204460492503130808472633361816 × 10-16
• `.MAX_SAFE_INTEGER: number` [ES6]

The largest integer that JavaScript can represent unambiguously (253−1).

• `.MAX_VALUE: number` [ES1]

The largest positive finite JavaScript number.

• Approximately: 1.7976931348623157 × 10308
• `.MIN_SAFE_INTEGER: number` [ES6]

The smallest integer that JavaScript can represent unambiguously (−253+1).

• `.MIN_VALUE: number` [ES1]

The smallest positive JavaScript number. Approximately 5 × 10−324.

• `.NaN: number` [ES1]

The same as the global variable `NaN`.

• `.NEGATIVE_INFINITY: number` [ES1]

The same as `-Number.POSITIVE_INFINITY`.

• `.POSITIVE_INFINITY: number` [ES1]

The same as the global variable `Infinity`.

#### 16.11.3 Static methods of `Number`

• `.isFinite(num: number): boolean` [ES6]

Returns `true` if `num` is an actual number (neither `Infinity` nor `-Infinity` nor `NaN`).

``````> Number.isFinite(Infinity)
false
> Number.isFinite(-Infinity)
false
> Number.isFinite(NaN)
false
> Number.isFinite(123)
true``````
• `.isInteger(num: number): boolean` [ES6]

Returns `true` if `num` is a number and does not have a decimal fraction.

``````> Number.isInteger(-17)
true
> Number.isInteger(33)
true
> Number.isInteger(33.1)
false
> Number.isInteger('33')
false
> Number.isInteger(NaN)
false
> Number.isInteger(Infinity)
false``````
• `.isNaN(num: number): boolean` [ES6]

Returns `true` if `num` is the value `NaN`:

``````> Number.isNaN(NaN)
true
> Number.isNaN(123)
false
> Number.isNaN('abc')
false``````
• `.isSafeInteger(num: number): boolean` [ES6]

Returns `true` if `num` is a number and unambiguously represents an integer.

• `.parseFloat(str: string): number` [ES6]

Coerces its parameter to string and parses it as a floating point number. For converting strings to numbers, `Number()` (which ignores leading and trailing whitespace) is usually a better choice than `Number.parseFloat()` (which ignores leading whitespace and illegal trailing characters and can hide problems).

``````> Number.parseFloat(' 123.4#')
123.4
> Number(' 123.4#')
NaN``````
• `.parseInt(str: string, radix=10): number` [ES6]

Coerces its parameter to string and parses it as an integer, ignoring leading whitespace and illegal trailing characters:

``````> Number.parseInt('  123#')
123``````

The parameter `radix` specifies the base of the number to be parsed:

``````> Number.parseInt('101', 2)
5
> Number.parseInt('FF', 16)
255``````

Do not use this method to convert numbers to integers: coercing to string is inefficient. And stopping before the first non-digit is not a good algorithm for removing the fraction of a number. Here is an example where it goes wrong:

``````> Number.parseInt(1e21, 10) // wrong
1``````

It is better to use one of the rounding functions of `Math` to convert a number to an integer:

``````> Math.trunc(1e21) // correct
1e+21``````

#### 16.11.4 Methods of `Number.prototype`

(`Number.prototype` is where the methods of numbers are stored.)

• `.toExponential(fractionDigits?: number): string` [ES3]

Returns a string that represents the number via exponential notation. With `fractionDigits`, we can specify, how many digits should be shown of the number that is multiplied with the exponent (the default is to show as many digits as necessary).

Example: number too small to get a positive exponent via `.toString()`.

``````> 1234..toString()
'1234'

> 1234..toExponential() // 3 fraction digits
'1.234e+3'
> 1234..toExponential(5)
'1.23400e+3'
> 1234..toExponential(1)
'1.2e+3'``````

Example: fraction not small enough to get a negative exponent via `.toString()`.

``````> 0.003.toString()
'0.003'
> 0.003.toExponential()
'3e-3'``````
• `.toFixed(fractionDigits=0): string` [ES3]

Returns an exponent-free representation of the number, rounded to `fractionDigits` digits.

``````> 0.00000012.toString() // with exponent
'1.2e-7'

> 0.00000012.toFixed(10) // no exponent
'0.0000001200'
> 0.00000012.toFixed()
'0'``````

If the number is 1021 or greater, even `.toFixed()` uses an exponent:

``````> (10 ** 21).toFixed()
'1e+21'``````
• `.toPrecision(precision?: number): string` [ES3]

Works like `.toString()`, but `precision` specifies how many digits should be shown. If `precision` is missing, `.toString()` is used.

``````> 1234..toPrecision(3)  // requires exponential notation
'1.23e+3'

> 1234..toPrecision(4)
'1234'

> 1234..toPrecision(5)
'1234.0'

> 1.234.toPrecision(3)
'1.23'``````
• `.toString(radix=10): string` [ES1]

Returns a string representation of the number.

By default, we get a base 10 numeral as a result:

``````> 123.456.toString()
'123.456'``````

If we want the numeral to have a different base, we can specify it via `radix`:

``````> 4..toString(2) // binary (base 2)
'100'
> 4.5.toString(2)
'100.1'

> 255..toString(16) // hexadecimal (base 16)
'ff'
> 255.66796875.toString(16)
'ff.ab'

> 1234567890..toString(36)
'kf12oi'``````

`Number.parseInt()` provides the inverse operation: it converts a string that contains an integer (no fraction!) numeral with a given base, to a number.

``````> Number.parseInt('kf12oi', 36)
1234567890``````

#### 16.11.5 Sources Quiz: advanced

See quiz app.