Я заметил, что они оцениваются как true:
(1 + Number.MIN_VALUE) === 1
Object.is(1 + Number.MIN_VALUE, 1)
Из документации :
Свойство статических данных Number.MIN_VALUE представляет наименьшее положительное числовое значение, которое можно представить в JavaScript.
Мои вопросы:
Поскольку Number.MIN_VALUE не равно нулю, почему прибавление его к заданному числу не приводит к получению другого числа?
Какое минимальное значение можно прибавить к данному числу, чтобы получить другое число?
См.: stackoverflow.com/questions/17849101/…
Поскольку причина (1.) одинакова для всех языков, использующих ieee 475, вы можете посмотреть stackoverflow.com/questions/41317661/…
Отвечает ли это на ваш вопрос? Математика с плавающей запятой не работает?
@derpirscher Нет, я знаю, что математика с плавающей запятой странная. Мне было интересно, почему Number.MIN_VALUE в некоторых случаях оказывается эквивалентным нулю. Это из-за странностей с плавающей запятой, но это другой вопрос.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


По вашим вопросам:
Для более надежных сравнений из-за особенностей внутреннего представления с плавающей запятой вы можете сравнивать следующим образом:
const x = 0.1, y = 0.2, expectedResult = 0.3;
function equalNumber(a,b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.info('===', x + y === expectedResult);
console.info('equalNumber', equalNumber((x+y), expectedResult));Что касается вашего второго вопроса, то число, которое вы запрашиваете, — Number.EPSILON.
Обратите внимание, что с увеличением чисел точность снижается, поэтому это не очень надежный способ проверки равенства. Для получения дополнительной информации прочитайте ответ @Amadan или прочитайте на MDN.
Спасибо! Я просто проделал небольшой цикл, чтобы найти наименьшее число, которое можно прибавить к 1, и, конечно же, результатом было то же значение, что и Number.EPSILON, о котором я до сих пор не знал. let last = 0, test = 1; while (1 + test !== 1) { last = test; test /= 2; } console.info(last);
return (a - b) < Number.EPSILON; не является общим решением для сравнения чисел с плавающей запятой. Как сравнивать числа с плавающей запятой всегда зависит от варианта использования. Кроме того, добавление Number.EPSILON к числу не гарантирует, что оно изменится, и это не самое маленькое число, которое приведет к изменению (это верно только при добавлении к 1).
@t.niese Не стесняйтесь дать более точный и исчерпывающий ответ. Я с нетерпением жду, что!
Какое минимальное значение можно прибавить к данному числу, чтобы получить другое число?
Я не уверен, что существует элегантный способ сделать это в JavaScript. К счастью, способ представления чисел с плавающей запятой одинаков в большинстве языков программирования, поэтому мы можем найти ответ в другом месте. В Python, например, есть метод, который сообщает следующее представимое число с плавающей запятой после заданного в заданном направлении. (C тоже так делает; Python на самом деле просто привязывается к C.) Итак, первое число с плавающей запятой после 1.0 (в направлении положительной бесконечности):
import math
math.nextafter(1.0, math.inf)
# => 1.0000000000000002
Наименьшее число, которое вы можете добавить к 1.0, чтобы изменить его, должно составлять где-то около половины разницы из-за округления:
x1 = (math.nextafter(1.0, math.inf) - 1.0) / 2.0
x1
# => 1.1102230246251565e-16
1.0 + x1
# => 1.0
x2 = math.nextafter(x1, math.inf)
x2
# => 1.1102230246251568e-16
1.0 + x2
# => 1.0000000000000002
Таким образом, x1 и x2 являются соседними числами с плавающей запятой (т. е. между ними нет другого числа с плавающей запятой), где одно слишком мало, чтобы иметь значение в дополнение к 1.0, а другого достаточно.
Мы можем вернуть его в JavaScript, чтобы подтвердить:
x1 = 1.1102230246251565e-16
x2 = 1.1102230246251568e-16
console.info(`1.0 + ${x1} = ${1.0 + x1}`)
console.info(`1.0 + ${x2} = ${1.0 + x2}`)Поскольку числа с плавающей запятой теряют точность по мере увеличения величины, «минимальное значение, которое можно добавить к данному числу, чтобы получить другое число», зависит от числа: то, что работает для 1.0, не будет работать для 100.0.
К сожалению, в JavaScript нет метода nextafter. На вопрос Быстрая функция nextafter в JavaScript есть пара ответов, которые претендуют на ее реализацию, но я недостаточно силен математически, чтобы ручаться за их правильность.
Из вышеизложенного также видно, что наименьшее число, которое можно добавить к 1.0, чтобы изменить ситуацию, на самом деле не Number.EPSILON, а чуть больше половины, и это специфично для случая 1.0. Number.EPSILON достаточно велико, чтобы изменить 2.0000000000000004, следующее число с плавающей запятой после 2.0:
n1 = 2.0
n2 = 2.0000000000000004
console.info(`${n1} + Number.EPSILON = ${n1 + Number.EPSILON}`)
console.info(`${n2} + Number.EPSILON = ${n2 + Number.EPSILON}`)
Интересный вопрос! У меня нет ответа в голове, но я бы начал с понимания того, как представлены числа. Точность чисел снижается по мере удаления от 0. Возможно, уже при 1 точности недостаточно, чтобы различить различия MIN_VALUE.. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…