By Axel Rauschmayer
This blog post describes the new number and Math
features of ECMAScript 6.
Overview
You can now specify integers in binary and octal notation:
> 0xFF // ES5: hexadecimal
255
> 0b11 // ES6: binary
3
> 0o10 // ES6: octal
8
The global object Number
gained a few new properties. Among others:
Number.EPSILON
for comparing
 Methods and constants for determining whether an integer is within the signed 53 bit range that can be safely represented by JavaScript.
New integer literals
ECMAScript 5 already has literals for hexadecimal integers:
> 0x9
9
> 0xA
10
> 0x10
16
> 0xFF
255
ECMAScript 6 brings two new kinds of integer literals:

Binary literals have the prefix 0b
or 0B
:
> 0b11
3
> 0b100
4

Octal literals have the prefix 0o
or 0O
(yes, that’s a zero followed by the capital letter O; you’ll be fine if you use the first variant):
> 0o7
7
> 0o10
8
Remember that the method Number.prototype.toString(radix)
can be used to convert numbers back:
> (255).toString(16)
'ff'
> (4).toString(2)
'100'
> (8).toString(8)
'10'
Use case for octal literals: Unixstyle file permissions
In the Node.js file system module, several functions have the parameter mode
. Its value is used to specify file permissions, via an encoding that is a holdover from Unix:
 Permissions are specified for three categories of users:
 User: the owner of the file
 Group: the members of the group associated with the file
 All: everyone
 Per category, the following permissions can be granted:
 r (read): the users in the category are allowed to read the file
 w (write): the users in the category are allowed to change the file
 x (execute): the users in the category are allowed to run the file
That means that permissions can be represented by 9 bits (3 categories with 3 permissions each):

User 
Group 
All 
Permissions 
r, w, x 
r, w, x 
r, w, x 
Bit 
8, 7, 6 
5, 4, 3 
2, 1, 0 
The permissions of a single category of users are stored in 3 bits:
Bits 
Permissions 
Octal digit 
000 
––– 
0 
001 
––x 
1 
010 
–w– 
2 
011 
–wx 
3 
100 
r–– 
4 
101 
r–x 
5 
110 
rw– 
6 
111 
rwx 
7 
That means that octal numbers are a compact representation of all permissions, you only need 3 digits, one digit per category of users. Two examples:
 755 = 111,101,101: I can change, read and execute; everyone else can only read and execute.
 640 = 110,100,000: I can read and write; group members can read; everyone can’t access at all.
parseInt()
and the new integer literals
parseInt()
has the following signature:
parseInt(string, radix?)
It provides special support for the hexadecimal literal notation – the prefix 0x
(or 0X
) of string
is removed if:
radix
is missing or 0. Then radix
is set to 16.
radix
is already 16.
For example:
> parseInt('0xFF')
255
> parseInt('0xFF', 0)
255
> parseInt('0xFF', 16)
255
In all other cases, digits are only parsed until the first nondigit:
> parseInt('0xFF', 10)
0
> parseInt('0xFF', 17)
0
parseInt()
does not have special support for binary or octal literals!
> parseInt('0b111')
0
> parseInt('0b111', 2)
0
> parseInt('111', 2)
7
> parseInt('0o10')
0
> parseInt('0o10', 8)
0
> parseInt('10', 8)
8
If you want to parse these kinds of literals, you need to use Number()
:
> Number('0b111')
7
> Number('0o10')
8
New Number
constructor properties
This section describes new properties that the constructor Number
has picked up in ECMAScript 6.
Previously global functions
Four numberrelated functions are already available as global functions and have been added (with no or little modifications) to Number
, as methods: isFinite
, isNaN
, parseFloat
and parseInt
.
Number.isFinite(number)
Is number
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
The advantage of this method is that it does not coerce its parameter to number (whereas the global function does):
> Number.isFinite('123')
false
> isFinite('123')
true
Number.isNaN(number)
Is number
the value NaN
? Making this check via ===
is hacky. NaN
is the only value that is not equal to itself:
> let x = NaN;
> x === NaN
false
Therefore, this expression is used to check for it
> x !== x
true
Using Number.isNaN()
is more selfdescriptive:
> Number.isNaN(x)
true
Number.isNan()
also has the advantage of not coercing its parameter to number (whereas the global function does):
> Number.isNaN('???')
false
> isNaN('???')
true
Number.parseFloat
and Number.parseInt
The following two methods work exactly like the global functions with the same names. They were added to Number
for completeness sake; now all numberrelated functions are available there.
Number.parseFloat(string)
Number.parseInt(string, radix)
Number.EPSILON
Especially with decimal fractions, rounding errors can become a problem in JavaScript. For example, the
> 0.1 + 0.2 === 0.3
false
Number.EPSILON
specifies a reasonable margin of error when comparing floating point numbers. It provides a better way to compare floating point values, as demonstrated by the following function.
function epsEqu(x, y) {
return Math.abs(x  y) < Number.EPSILON;
}
console.log(epsEqu(0.1+0.2, 0.3)); // true
Number.isInteger(number)
JavaScript has only floating point numbers (doubles). Accordingly, integers are simply floating point numbers without a decimal fraction.
Number.isInteger(number)
returns true
if number
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
Safe Integers
JavaScript numbers have only enough storage space to represent 53 bit signed integers. That is, integers i in the range −2^53^ < i < 2^53^ are safe. What exactly that means is explained momentarily. The following properties help determine whether a JavaScript integer is safe:
Number.isSafeInteger(number)
Number.MIN_SAFE_INTEGER
Number.MAX_SAFE_INTEGER
The notion of safe integers centers on how mathematical integers are represented in JavaScript. In the range (−2^53^, 2^53^) (excluding the lower and upper bounds), JavaScript integers are safe: there is a onetoone mapping between them and the mathematical integers they represent.
Beyond this range, JavaScript integers are unsafe: two or more mathematical integers are represented as the same JavaScript integer. For example, starting at 2^53^, JavaScript can represent only every second mathematical integer:
> Math.pow(2, 53)
9007199254740992
> 9007199254740992
9007199254740992
> 9007199254740993
9007199254740992
> 9007199254740994
9007199254740994
> 9007199254740995
9007199254740996
> 9007199254740996
9007199254740996
> 9007199254740997
9007199254740996
Therefore, a safe JavaScript integer is one that unambiguously represents a single mathematical integer.
The properties of Number
The two Number
properties specifying the lower and upper bound of safe integers could be defined as follows:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)1;
Number.MIN_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
Number.isSafeInteger()
determines whether a JavaScript number is a safe integer and could be defined as follows:
Number.isSafeInteger = function (n) {
return (typeof n === 'number' &&
Math.round(n) === n &&
Number.MIN_SAFE_INTEGER <= n &&
n <= Number.MAX_SAFE_INTEGER);
}
For a given value n
, this function first checks whether n
is a number and an integer. If both checks succeed, n
is safe if it is greater than or equal to MIN_SAFE_INTEGER
and less than or equal to MAX_SAFE_INTEGER
.
Safe results of arithmetic computations
How can we make sure that results of arithmetic computations are correct? For example, the following result is clearly not correct:
> 9007199254740990 + 3
9007199254740992
We have two safe operands, but an unsafe result:
> Number.isSafeInteger(9007199254740990)
true
> Number.isSafeInteger(3)
true
> Number.isSafeInteger(9007199254740992)
false
The following result is also incorrect:
> 9007199254740995  10
9007199254740986
This time, the result is safe, but one of the operands isn’t:
> Number.isSafeInteger(9007199254740995)
false
> Number.isSafeInteger(10)
true
> Number.isSafeInteger(9007199254740986)
true
Therefore, the result of applying an integer operator op
is guaranteed to be correct only if all operands and the result are safe. More formally:
isSafeInteger(a) && isSafeInteger(b) && isSafeInteger(a op b)
implies that a op b
is a correct result.
Source of this section
Math
The global object Math
has several new methods in ECMAScript 6.
Various numerical functionality
Math.sign(x)
Returns the sign of x
as 1
or +1
. Unless x
is either NaN
or zero; then x
is returned[1].
[1]: While that is something that you normally don’t see, that means that 0
produces the result 0
and +0
produces the result +0
.
> Math.sign(8)
1
> Math.sign(3)
1
> Math.sign(0)
0
> Math.sign(NaN)
NaN
> Math.sign(Infinity)
1
> Math.sign(Infinity)
1
Math.trunc(x)
Removes the decimal fraction of x
.
> Math.trunc(3.1)
3
> Math.trunc(3.9)
3
> Math.trunc(3.1)
3
> Math.trunc(3.9)
3
Math.cbrt(x)
Returns the cube root of x
(∛x).
> Math.cbrt(8)
2
Using 0 instead of 1 with exponentiation and logarithm
JavaScript numbers (doubles) close to zero are stored with a higher precision.
1 × 10^−16^
> 1e16 === 0
false
> 1 + 1e16 === 1
true
Math.expm1(x)
Returns Math.exp(x)1
. The inverse of Math.log1p()
.
Therefore, this method provides higher precision whenever Math.exp()
has results close to 1.
> Math.expm1(1e10)
1.00000000005e10
> Math.exp(1e10)1
1.000000082740371e10
> var Decimal = require('decimal.js').config({precision:50});
> new Decimal(1e10).exp().minus(1).toString()
'1.000000000050000000001666666666708333333e10'
Math.log1p(x)
Returns Math.log(1 + x)
. The inverse of Math.expm1()
.
Therefore, this method lets you specify parameters that are close to 1 with a higher precision.
We have already established that 1 + 1e16 === 1
. Therefore, it is no surprise that the following two calls of log()
produce the same result:
> Math.log(1 + 1e16)
0
> Math.log(1 + 0)
0
In contrast, log1p()
produces different results:
> Math.log1p(1e16)
1e16
> Math.log1p(0)
0
Logarithms to base 2 and 10
Math.log2(x)
Computes the logarithm to base 2.
> Math.log2(8)
3
Math.log10(x)
Computes the logarithm to base 10.
> Math.log10(100)
2
Support for compiling to JavaScript
Emscripten pioneered a coding style that was later picked up by asm.js: The operations of a virtual machine (think bytecode) are expressed in static subset of JavaScript. That subset can be executed efficiently by JavaScript engines: If it is the result of a compilation from C++, it runs at about 70% of native speed.
Math.fround(x)
Rounds x
to a 32 bit floating point value (float
). Used by asm.js to tell an engine to internally use a float
value.
Math.imul(x, y)
Multiplies the two 32 bit integers x
and y
and returns the lower 32 bits of the result. This is the only 32 bit basic math operation that can’t be simulated by using a JavaScript operator and coercing the result back to 32 bits. For example, idiv
could be implemented as follows:
function idiv(x, y) {
return (x / y)  0;
}
In contrast, multiplying two large 32 bit integers may produce a double that is so large that lower bits are lost.
Bitwise operations

Math.clz32(x)
Counts the leading zero bits in the 32 bit integer x
.
> Math.clz32(0b01000000000000000000000000000000)
1
> Math.clz32(0b00100000000000000000000000000000)
2
> Math.clz32(2)
30
> Math.clz32(1)
31
Trigonometric methods

Math.sinh(x)
Computes the hyperbolic sine of x
.

Math.cosh(x)
Computes the hyperbolic cosine of x
.

Math.tanh(x)
Computes the hyperbolic tangent of x
.

Math.asinh(x)
Computes the inverse hyperbolic sine of x
.

Math.acosh(x)
Computes the inverse hyperbolic cosine of x
.

Math.atanh(x)
Computes the inverse hyperbolic tangent of x
.

Math.hypot(...values)
Computes the square root of the sum of squares of its arguments.
Source:: 2ality