Правильная математика в ES6+

0.1 + 0.2 === 0.3

Наверняка вы уже сталкивались с тем, что в JS арифметика с числами не всегда выдает ожидаемый результат, в силу особенностей работы с числами. Например:

0.1 * 0.2
0.020000000000000004
0.3 - 0.1
0.19999999999999998

Т.е. если мы просто напишем логику, в которое однажды произойдет следующее условие:

0.1 + 0.2 === 0.3
false

То наше условие не сработает. Как быть?

Машинное эпсилон округление

Машинное эпсилон было введено в ES6.

Машинный ноль — числовое значение с таким отрицательным порядком, которое воспринимается машиной как ноль.
Машинное эпсилон — числовое значение, меньше которого невозможно задавать относительную точность для любого алгоритма, возвращающего вещественные числа. Абсолютное значение «машинного эпсилон» зависит от разрядности сетки, типа (разрядности) используемых при расчетах чисел, и от принятой в конкретном трансляторе структуры представления вещественных чисел (количества бит, отводимых на мантиссу и на порядок). Формально машинное эпсилон обычно определяют как минимальное из чисел eps, для которого 1+eps>1 при машинных расчетах с числами данного типа. Альтернативное определение — максимальное положительное eps, для которого справедливо равенство 1+eps=1.
Практическая важность машинного эпсилон связана с тем, что два (отличных от нуля) числа являются одинаковыми с точки зрения машинной арифметики, если их относительная разность по модулю меньше (при определении первого типа) или не превосходит (при определении второго типа) машинного эпсилон.

Машинное эпсилон округление обеспечивает разумный предел погрешности при сравнении двух чисел с плавающей точкой.

Реализуем функцию equal

const eq = (a, b) =>
Math.abs(a-b) < Number.EPSILON * Math.max(Math.abs(a),Math.abs(b))
;
eq(.1 + .2, .3) // true