Codementor Events

JS WTF 🦄 with Math

Published Feb 19, 2018Last updated Aug 18, 2018
JS WTF 🦄 with Math

max() vs min()

Math.max() > Math.min()   // false

WHAT?max is not bigger than min? NO 😱 but there’s a reason for it.

By definition Math.max([value1[, value2[, ...]]]) returns the largest of the given numbers. However, when no arguments are provided it returns the minimum possible value, which is -Infinity.

As you guessed Math.min() returns Infinity when no arguments are provided, i.e. the highest possible value.

Therefore, when comparing Math.max() > Math.min() is not even fair.

It’s not fair.

-Infinity its way lower than Infinity.

0.1 + 0.2

0.1 + 0.2 === 0.3   // false

This is not a problem of JS to be fair. This is floating point math.

Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with some degree of inaccuracy. That’s why, more often than not, .1 + .2 != .3 — 0.300000000000004.com

The problem lies on the way machines store numeric values (i.e. binary representation.) In the case of integer values , only integers that can be represented as number times the power of two can be exactly represented.

As for rational numbers (such as 0.1, which is 1/10) only values whose the denominator can be represented as a power of two can be exactly represented.

Although 0.1 and 0.2 can be exactly represented in base 10 the same is not true for base 2. When this happens our machines create an approximation of their true value (which results into a repeating value).

> 0.1.toString(2)
'0.0001100110011001100110011001100110011001100110011001101'

> 0.2.toString(2)
'0.001100110011001100110011001100110011001100110011001101'

Therefore, the result of 0.1 + 0.2 would be a repeating value.

Which in base 10 is represented by 0.30000000000000004.

[] + {}

[] + {}     // '[object Object]'
{} + []     // 0

The + operator has a different behaviour in each example.

It behaves as an addition operator for the expression [] + {}, and as unary operator for the expression {} + [].

When interpreting the expression [] + {} JS identifies an addition operation but before adding both operands it converts them to primitives. This is done by executing the static method .toString().

As a result we end up with the operation '' + '[object Object]'.

Only at this stage JS knows that the addition operator + has the purpose of concatenating strings. And the final value of '[object Object]' is returned.

Next!

For the expression {} + [], the first operant is a pair of curly brackets (i.e. an empty block.) This empty block means “nothing to do”. Therefore JS moves forward on executing the expression.

When reaching the + operator it behaves as an unary operator because it has no left operand. Through coercion [] is translated into 0.

true + true

true + true === 2   // true
true - true === 0   // true
true === 1          // false

Here, the + operator behaves as an additional operator and adds both operands. However before it can do that it needs to convert them ToNumber.

By definition, ToNumber returns 1 if the argument is true , 0 if the argument is false.

For this reason, our expression true + true translates into 1 + 1, which is 2.

1 < 2 < 3

1 < 2 < 3   // true
3 > 2 > 1   // false

Spoiler alert: It’s coercion again 😎

Here, it may be useful to go step-by-step for both examples.

1 < 2 < 3

  1. Because JS interprets and executes the expressions from left to right , it will run the expression 1 < 2 first, therefore true < 3;
  2. Next, coercion , ToNumber(true) < 3 which translates into 1 < 3;
  3. Return true (because 1 is lower than 3);

3 > 2 > 1

  1. Because 3 > 2 is true then true > 1;
  2. ToNumber(true) > 1 translates into 1 > 1 ( coercion again 👌);
  3. Return false (because 1 is not higher than 1);

‘5’ + 3

'5' + 3     // '53'
'5' - 3     // 2

By definition the addition operator performs either string concatenation or numeric addition.

When one of the operands is a string, JS converts the other operand to a string and returns the concatenation of both. In the case of '5' + 3, because the left operand is a string the final result is the concatenation of both'5' and ToString(3), which is '53'.

The subtraction operator performs a subtraction with the two operands.

However, when an operator is not of the type Number it is converted ToNumber. For that reason, the string '5' is converted into the number 5 to which is subtracted 3. The final result is 2.

< your weirdness >

If you find any weirdness that should be here, please let me know 👐

Thanks to 🍻


Be sure to check out my other articles on JS WTF

JS WTF 🦄 with Arrays

JS WTF 🦄 with Number

Discover and read more posts from Tiago Lopes Ferreira
get started
post commentsBe the first to share your opinion
Joel Sánchez (kazer)
6 years ago
Show more replies