В дополнение к другим правильным ответам вы можете рассмотреть возможность масштабирования ваших значений, чтобы избежать проблем с арифметикой с плавающей запятой.
Например:
var result = 1.0 + 2.0; // result === 3.0 returns true
... вместо:
var result = 0.1 + 0.2; // result === 0.3 returns false
Выражение 0.1 + 0.2 === 0.3
возвращает false
в JavaScript, но, к счастью, целочисленная арифметика в плавающей запятой является точной, поэтому ошибки с десятичным представлением можно избежать путем масштабирования.
В качестве практического примера, чтобы избежать проблем с плавающей запятой, где точность имеет первостепенное значение, рекомендуется обрабатывать деньги как целое число, представляющее число центов: 2550
центов вместо 25.50
долларов.
1 Дуглас Крокфорд: JavaScript: Хорошие детали: Приложение A - Ужасные части (стр. 105) .
Используется функция библиотеки sqrt
для обработки ошибок. См. Документацию glibc: 20.5.4. Отчеты об ошибках с помощью математических функций : набор математических функций errno
для совместимости с системами, которые не имеют флагов исключений IEEE754. Связано: glibc's math_error(7)
справочная страница.
В качестве оптимизации сначала пытается выполнить квадратный корень с помощью встроенной команды sqrtsd
, а затем проверяет результат на себя, используя ucomisd
, которая устанавливает флаги следующим образом:
blockquote>CASE (RESULT) OF UNORDERED: ZF,PF,CF 111; GREATER_THAN: ZF,PF,CF 000; LESS_THAN: ZF,PF,CF 001; EQUAL: ZF,PF,CF 100; ESAC;
В частности, сравнение
QNaN
с самим собой вернетUNORDERED
, что и будет get, если вы попытаетесь взять квадратный корень из отрицательного числа. Это распространяется на ветвьjp
. Проверкаje
- это просто паранойя, проверяющая точное равенство.
Также обратите внимание, что gcc имеет параметр
-fno-math-errno
, который пожертвует этой обработкой ошибок для скорости. Этот параметр является частью-ffast-math
, но может использоваться сам по себе, не позволяя оптимизаторам, изменяющим результат.
sqrtsd
сам по себе производит NaN для отрицательных и NaN-входов и устанавливает IEEE754 Неверный флаг. Проверка и ветвь - только , чтобы сохранить семантикуerrno
-setting, на которую не полагается большинство кода.
-fno-math-errno
является значением по умолчанию в Darwin (OS X) , где математическая библиотека никогда не устанавливаетerrno
, поэтому функции могут быть встроены без этой проверки.