Black lives matter

(Ad, please don’t block)

This blog post explains how JavaScript displays numbers. It also examines when JavaScript uses exponential notation and when it uses fixed notation.

This post is part of a series on JavaScript numbers that currently comprises the following other post:

[ "+" | "-" ] digit+ [ "." digit+ ]and exponential notation

[ "+" | "-" ] digit [ "." digit+ ] "e" [ "+" | "-" ] digit+An example of exponential notation is

The value of that number issignificandeexponent

significand × 10Hence,^{exponent}

- Use exponential notation if there are more than 21 digits before the decimal point. Example:
> 1234567890123456789012 1.2345678901234568e+21 > 123456789012345678901 123456789012345680000

- Use exponential notation if the number starts with “0.” followed by more than five zeros. Example:
> 0.0000003 3e-7 > 0.000003 0.000003

- Otherwise, use fixed notation.

- The mantissa of 12.34 is 1234.
- The mantissa of 0.00045 is 45
- The mantissa of 1000 is 1
- The mantissa of −27 is −27

mantissa × 10The ECMAScript specification varies this idea by expressing a number as^{exponent}

mantissa × 10Hence, the previous exponent is now pointPos−digitCount. digitCount denotes the “length” of the mantissa, the number of digits that it has. Based on that definition, pointPos works as follows.^{pointPos−digitCount}

- pointPos = 0: point is before the digits.
> 123 * Math.pow(10, 0 - 3) 0.123

- pointPos ≥ 1: point is after the 1st (2nd, etc.) digit. If pointPos is less than digitCount then then the point appears “inside” the mantissa:
> 123 * Math.pow(10, 1 - 3) 1.23

If pointPos is the same as digitCount then the point appears after the last digit of the mantissa.> 123 * Math.pow(10, 3 - 3) 123

If pointPos is greater than digitCount then zeros are inserted after the mantissa and before the point.> 123 * Math.pow(10, 5 - 3) 12300

- pointPos ≤ −1: one (two, etc.) zeros appear after the point and before the mantissa.
> 123 * Math.pow(10, -2 - 3) 0.00123

mantissa × 10The algorithm has four main cases (the last case covers the actual algorithm’s last two cases).^{pointPos−digitCount}

**No decimal point:**digitCount ≤ pointPos ≤ 21

Print the digits (without leading zeros), followed by pointPos−digitCount zeros.**Decimal point inside the mantissa:**0 < pointPos ≤ 21, pointPos < digitCount

Display the pointPos first digits of the mantissa, a point and then the remaining digitCount−pointPos digits.**Decimal point comes before the mantissa:**−6 < pointPos ≤ 0

Display a 0 followed by a point, −pointPos zeros and the mantissa.**Exponential notation:**pointPos ≤ -6 or pointPos > 21

Display the first digit of the mantissa. If there are more digits then display a point and the remaining digits. Next, display the character`e`and a plus or minus sign (depending on the sign of pointPos−1), followed by the absolute value of pointPos−1. Therefore, the result looks as follows.mantissa

_{0}[ "." mantissa_{1..digitCount}]

"e" signChar(pointPos−1) abs(pointPos−1)

> 15..toString(2) '1111' > 65535..toString(16) 'ffff'The radix must be at least 2 and at most 36. Any radix greater than 10 leads to alphabetical characters being used as digits, which explains the maximum 36, as the latin alphabet has 26 characters.

> 1234567890..toString(36) 'kf12oi'The global function

> parseInt('kf12oi', 36) 1234567890If the radix is 10, the algorithm from Sect. 1 is used to convert the number to a string.

Force more precision when `toString()` would also use exponential notation. Results are mixed, because one reaches the limits of the precision that can be achieved when converting binary numbers to a decimal notation.

> 1234567890123456789012..toString() '1.2345678901234568e+21' > 1234567890123456789012..toExponential(20) '1.23456789012345677414e+21'

Get exponential notation when numbers are not large enough.

> 1234..toString() '1234' > 1234..toExponential(5) '1.23400e+3' > 1234..toExponential() '1.234e+3'

Get exponential notation when non-zero numbers are not small enough.

> 0.003.toString() '0.003' > 0.003.toExponential(4) '3.0000e-3' > 0.003.toExponential() '3e-3'

> 1234567890123456789012..toFixed() '1.2345678901234568e+21' > 1234567890123456789012..toString() '1.2345678901234568e+21'Otherwise, you will get a fixed point representation of the number, rounded to

> 0.0000003.toFixed(10) '0.0000003000' > 0.0000003.toString() '3e-7'

> 1234..toPrecision(3) '1.23e+3' > 1234..toPrecision(4) '1234' > 1234..toPrecision(5) '1234.0' > 1.234.toPrecision(3) '1.23'Obviously, you need the exponential notation to display 1234 with a precision of 3 digits.

It is interesting to note that you can always append `e x` to a number and it will be multiplied by 10

> 123e3 123000 > 123e-3 0.123