Секреты чисел в JS

Ошибки округления

В Javascript могут происходить интересные вещи, если вы не знаете, как он работает внутри. Например, числа с плавающей запятой вызывают некоторые ошибки округления. 0,1 и 0,2 не могут быть представлены точно. Следовательно, 0,1 + 0,2 === 0,3 дает ложь.

Итак, почему это происходит? Javascript использует 32-битную систему счисления с плавающей запятой. Для представления многих десятичных знаков в двоичном формате требуется бесконечное количество цифр. Попытка вычислить 0,1 (1/10) приводит к неопределенному количеству десятичных знаков. Результатом 0.1 + 0.2 является 0.30000000000000004, что не равно 0.3.

Номер.ЭПСИЛОН

Number.EPSILON возвращает наименьший интервал между двумя представимыми числами. Это полезно для задачи с аппроксимацией с плавающей запятой.

function numberEquals(x: number, y: number) {
  return Math.abs(x — y) < Number.EPSILON;
}
numberEquals(0.1 + 0.2, 0.3); // true

Разница между 0.1 + 0.2 и 0.3 будет меньше Number.EPSILON.

Двойные точки

Числа могут быть преобразованы в строки с фиксированным количеством десятичных знаков. Если вы будете вызывать функцию toFixed() непосредственно для целого числа, вам нужно будет использовать нотацию с двойными точками, например: 5..toFixed(1) === ‘5.0’. Почему вы должны это делать? Просто потому, что первая запись через точку предназначена для представления чисел с плавающей запятой: 0.77.toFixed(1) === ‘0.7’
Вы можете использовать функцию toFixed() в предыдущем примере для сопоставления равенства (0.1 + 0.2).toFixed(1) === 0.3.toFixed(1)

Примечание. Примитивы в Javascript не являются объектами, но почему вы можете использовать ”string”.length, 0.77.toFixed(1)? Ну, Javascript создает специальный объект-оболочку со значением для примитива, когда вы вызываете метод, и удаляет его после выполнения.

Минимумы, максимумы

Number содержит интересные константы, которые представляют максимальные и минимальные целые числа и числа с плавающей запятой. В Javascript есть Infinity и -Infinity, но это не настоящие числа.

Number.MAX_SAFE_INTEGER возвращает наибольшее целое число. Это равно 9007199254740991 И это выражение верно:

Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true

Number.MAX_VALUE возвращает наибольшее число с плавающей запятой. Это равно 1.7976931348623157e+308. То же выражение для него:

Number.MAX_VALUE + 1.111 === Number.MAX_VALUE + 2.022; // true

Минимальные значения представлены Number.MIN_VALUE как наименьшее число с плавающей запятой, равное 5e-324, и Number.MIN_SAFE_INTEGER, равное -9007199254740991.
Number.MIN_VALUE также является ближайшим к нулю числом с плавающей запятой.

Number.MIN_VALUE — 1 === -1; // true

Почему это правда? Поскольку это выражение похоже на 0–1 === -1

Краткое содержание

Подытожим размер чисел Javascript:

-Infinity < Number.MIN_SAFE_INTEGER < Number.MIN_VALUE < 0 < Number.MAX_SAFE_INTEGER < Number.MAX_VALUE < Infinity

Когда вы работаете с числами с плавающей запятой, вы должны быть осторожны и учитывать ошибки округления, потому что некоторые числа не могут быть представлены точно. Вы можете использовать сторонние библиотеки или проверять различия между числами с помощью Number.EPSILON.

Фото автора Волкан Олмез на Unsplash