Like I did in previous articles on the series, I would love to point out that you should probably set up Babel and follow along the examples with either a REPL or the

`babel-node`

CLI and a file. That’ll make it so much easier for you tointernalize the conceptsdiscussed in the series. If you aren’t the“install things on my computer”kind of human, you might prefer to hop on CodePen and then click on the gear icon for JavaScript –they have a Babel preprocessor which makes trying out ES6 a breeze.Another alternative that’s also quite useful is to use Babel’s online REPL– it’ll show you compiled ES5 code to the right of your ES6 code for quick comparison.

Before getting into it, let me *shamelessly ask for your support* if you’re enjoying my ES6 in Depth series. Your contributions will go towards helping me keep up with the schedule, server bills, keeping me fed, and maintaining **Pony Foo** as a veritable source of JavaScript goodies.

Thanks for reading that, and let’s go into `Math`

improvements. For a bit of context you may want to look at the extensive article on `Number`

improvements from last week. Time to dig into `Math`

.

`Math`

Additions in ES6

There’s *heaps* of additions to `Math`

in ES6. Just like you’re used to, these are **static** methods on the `Math`

built-in. Some of these methods were specifically engineered towards making it easier to compile C into JavaScript, and you may never come across a need for them in day-to-day development – particularly not when it comes to front-end development. Other methods are complements to the existing rounding, exponentiation, and trigonometry API surface.

Below is a full list of methods added to `Math`

. They are grouped by functionality and sorted by relevance.

**Utility**`Math.sign`

– sign function of a number`Math.trunc`

– integer part of a number

**Exponentiation and Logarithmic**`Math.cbrt`

– cubic root of value, or`∛‾value`

`Math.expm1`

–`e`

to the`value`

minus`1`

, or`e`

^{value}- 1`Math.log1p`

– natural logarithm of`value + 1`

, or*ln*(value + 1)`Math.log10`

– base 10 logarithm of`value`

, or*log*_{10}(value)`Math.log2`

– base 2 logarithm of`value`

, or*log*_{2}(value)

**Trigonometry**`Math.sinh`

– hyperbolic sine of a number`Math.cosh`

– hyperbolic cosine of a number`Math.tanh`

– hyperbolic tangent of a number`Math.asinh`

– hyperbolic arc-sine of a number`Math.acosh`

– hyperbolic arc-cosine of a number`Math.atanh`

– hyperbolic arc-tangent of a number`Math.hypot`

– square root of the sum of squares

**Bitwise**`Math.clz32`

– leading zero bits in the 32-bit representation of a number

**Compile-to-JavaScript**`Math.imul`

–*C-like*32-bit multiplication`Math.fround`

– nearest single-precision float representation of a number

Let’s get right into it.

`Math.sign`

Many languages have a `Math.Sign`

method *(or equivalent)* that returns a vector like `-1`

, `0`

, or `1`

, depending on the sign of the provided input. Surely then, you would think JavaScript’s `Math.sign`

method does the same. Well, sort of. The JavaScript flavor of this method has two more alternatives: `-0`

, and `NaN`

.

```
Math.sign(1)
// <- 1
Math.sign(0)
// <- 0
Math.sign(-0)
// <- -0
Math.sign(-30)
// <- -1
Math.sign(NaN)
// <- NaN
Math.sign('foo')
// <- NaN, because Number('foo') is NaN
Math.sign('0')
// <- 0, because Number('0') is 0
Math.sign('-1')
// <- -1, because Number('-1') is -1
```

This is just one of those methods. It **grinds my gears.** After all the trouble we went through to document how methods ported over to `Number`

, such as `Number.isNaN`

, don’t indulge in unnecessary type coercion, why is it that `Math.sign`

*does* coerce its input? I have no idea. Most of the methods in `Math`

share this trait, though. The methods that were added to `Number`

don’t.

Sure, we’re not a statically typed language, we dislike throwing exceptions, and we’re fault tolerant – after all, this is one of the founding languages of the web. But was not coercing everything into a `Number`

too much to ask? Couldn’t we just return `NaN`

for *non-numeric* values?

I’d love for us to get over implicit casting, but it seems we’re *not quite there yet* for the time being.

`Math.trunc`

One of the oddities in `Math`

methods is how abruptly they were named. It’s like they were trying to save keystrokes or something. After all, it’s not like we stopped adding *super-precise* method names like `Object.getOwnPropertySymbols()`

. Why `trunc`

instead of `truncate`

, then? Who knows.

Anyways, `Math.trunc`

is a simple alternative to `Math.floor`

and `Math.ceil`

where we simply discard the decimal part of a number. Once again, the input is coerced into a numeric value through `Number(value)`

.

```
Math.trunc(12.34567)
// <- 12
Math.trunc(-13.58)
// <- -13
Math.trunc(-0.1234)
// <- -0
Math.trunc(NaN)
// <- NaN
Math.trunc('foo')
// <- NaN, because Number('foo') is NaN
Math.trunc('123.456')
// <- 123, because Number('123.456') is 123.456
```

While it still coerces any values into numbers, at least it stayed consistent with `Math.floor`

and `Math.ceil`

, enough that you could use them to create a simple polyfill for `Math.trunc`

.

```
Math.trunc = function truncate (value) {
return value > 0 ? Math.floor(value) : Math.ceil(value)
}
```

Another apt example of how *“succintly”* `Math`

methods have been named in ES6 can be found in `Math.cbrt`

*– although this one matches the pre-existing Math.sqrt method, to be fair.*

`Math.cbrt`

As hinted above, `Math.cbrt`

is short for *“cubic root”*. The examples below show the sorts of output it produces.

```
Math.cbrt(-1)
// <- -1
Math.cbrt(3)
// <- 1.4422495703074083
Math.cbrt(8)
// <- 2
Math.cbrt(27)
// <- 3
```

Not much explaining to do here. Note that this method *also* coerces non-numerical values into numbers.

```
Math.cbrt('8')
// <- 2, because Number('8') is 8
Math.cbrt('ponyfoo')
// <- NaN, because Number('ponyfoo') is NaN
```

Let’s move onto something else.

`Math.expm1`

This operation is the result of computing `e`

to the `value`

minus `1`

. In JavaScript, the `e`

constant is defined as `Math.E`

. The method below is a rough equivalent of `Math.expm1`

.

```
function expm1 (value) {
return Math.pow(Math.E, value) - 1
}
```

The `e`

operation can be expressed as ^{value}`Math.exp(value)`

as well.

```
function expm1 (value) {
return Math.exp(value) - 1
}
```

Note that this method has higher precision than merely doing `Math.exp(value) - 1`

, and should be the preferred alternative.

```
expm1(1e-20)
// <- 0
Math.expm1(1e-20)
// <- 1e-20
expm1(1e-10)
// <- 1.000000082740371e-10
Math.expm1(1e-10)
// <- 1.00000000005e-10
```

The inverse function of `Math.expm1`

is `Math.log1p`

.

`Math.log1p`

This is the natural logarithm of `value`

plus `1`

, –

– and the inverse function of *ln*(value + 1)`Math.expm1`

. The base `e`

logarithm of a number can be expressed as `Math.log`

in JavaScript.

```
function log1p (value) {
return Math.log(value + 1)
}
```

This method is **more precise** than executing the `Math.log(value + 1)`

operation by hand, just like the `Math.expm1`

case.

```
log1p(1.00000000005e-10)
// <- 1.000000082690371e-10
Math.log1p(1.00000000005e-10)
// <- 1e-10, exactly the inverse of Math.expm1(1e-10)
```

Next up is `Math.log10`

.

`Math.log10`

Base ten logarithm of a number –

.*log*_{10}(value)

```
Math.log10(1000)
// <- 3
```

You could polyfill `Math.log10`

using the `Math.LN10`

constant.

```
function log10 (value) {
return Math.log(x) / Math.LN10
}
```

And then there’s `Math.log2`

.

`Math.log2`

Base two logarithm of a number –

.*log*_{2}(value)

```
Math.log2(1024)
// <- 10
```

You could polyfill `Math.log2`

using the `Math.LN2`

constant.

```
function log2 (value) {
return Math.log(x) / Math.LN2
}
```

Note that the polyfilled version won’t be as precise as `Math.log2`

in some cases. Remember that the `<<`

operator means *“bitwise left shift”*.

```
Math.log2(1 << 29)
// <- 29
log2(1 << 29)
// <- 29.000000000000004
```

Naturally, you could use `Math.round`

or `Number.EPSILON`

to get around rounding issues.

`Math.sinh`

Returns the hyperbolic sine of `value`

.

`Math.cosh`

Returns the hyperbolic cosine of `value`

.

`Math.tanh`

Returns the hyperbolic tangent of `value`

.

`Math.asinh`

Returns the hyperbolic arc-sine of `value`

.

`Math.acosh`

Returns the hyperbolic arc-cosine of `value`

.

`Math.atanh`

Returns the hyperbolic arc-tangent of `value`

.

`Math.hypot`

Returns the square root of the sum of the squares of the arguments.

```
Math.hypot(1, 2, 3)
// <- 3.741657386773941
```

We could polyfill `Math.hypot`

by doing the operations manually. We can use `Math.sqrt`

to compute the square root and `Array.prototype.reduce`

combined with the spread operator to sum the squares. I’ll throw in an arrow function for good measure!

```
function hypot (...values) {
return Math.sqrt(values.reduce((sum, value) => sum + value * value, 0))
}
```

Surprisingly, our handmade method is more precise than the native one *(at least on Chrome 45)* for **this case in particular**.

```
Math.hypot(1, 2, 3)
// <- 3.741657386773941
hypot(1, 2, 3)
// <- 3.7416573867739413
```

And now for the **“ really fun”** methods!

`Math.clz32`

Definitely not immediately obvious, but the name for this method is an acronym for *“count leading zero bits in 32-bit binary representations of a number”*. Remember that the `<<`

operator means *“bitwise left shift”*, and thus…

```
Math.clz32(0)
// <- 32
Math.clz32(1)
// <- 31
Math.clz32(1 << 1)
// <- 30
Math.clz32(1 << 2)
// <- 29
Math.clz32(1 << 29)
// <- 2
```

Cool, and also probably the last time you’re going to see that method in use for the foreseeable future. For completeness’ sake, I’ll add a sentence about the pair of methods that were added mostly to aid with `asm.js`

compilation of C programs. *I doubt you’ll be using these directly, ever.*

`Math.imul`

Returns the result of a C-like 32-bit multiplication.

`Math.fround`

Rounds `value`

to the nearest 32-bit float representation of a number.

# Conclusions

Some nice methods rounding out the `Math`

API. It would’ve been nice to see additions to the tune of more flavors of `Math.random`

and similar utilities that end up being implemented by libraries in almost every large-enough application, such as Lodash’es `_.random`

and `_.shuffle`

.

That being said, any help towards making `asm.js`

faster and more of a reality are desperately welcome additions to the language.

## Comments (1)

The multiplication of two 32-bit integers is 64-bits wide. Does

`Math.imul`

return the lower 32-bit part, the 53-bit float part, or all 64-bits?