Задача
Плавающая точка не может хранить все десятичные значения точно. Поэтому при использовании форматов с плавающей запятой всегда будут ошибки округления входных значений.
Ошибки на входах курса приводят к ошибкам на выходе.
В случае дискретной функции или оператора на выходе могут быть большие различия вокруг точки, где функция или оператор дискретны.
Ввод и вывод для значений с плавающей запятой
Итак, при использовании переменных с плавающей запятой вы всегда должны знать об этом. И любой вывод, который вы хотите получить из вычисления с плавающей запятой, всегда должен быть отформатирован / обработан перед отображением с учетом этого.
Когда используются только непрерывные функции и операторы, часто выполняется округление до желаемой точности (не усекайте). Стандартные функции форматирования, используемые для преобразования чисел с плавающей точкой, обычно делают это для вас.
Поскольку при округлении добавляется ошибка, которая может привести к тому, что общая ошибка составляет более половины требуемой точности, выходные данные следует корректировать на основе ожидаемой точности входных данных и требуемой точности выходных данных. Вы должны
- Округлите ввод с ожидаемой точностью или убедитесь, что значения не могут быть введены с более высокой точностью.
- Добавьте к выходам небольшое значение перед округлением / форматированием, которое меньше или равно 1/4 требуемой точности и больше максимальной ожидаемой ошибки, вызванной ошибками округления на входе и во время расчета. Если это невозможно, комбинации точности используемого типа данных недостаточно, чтобы обеспечить желаемую точность вывода для ваших расчетов.
Эти 2 вещи обычно не выполняются, и в большинстве случаев различия, вызванные их отсутствием, слишком малы, чтобы быть важными для большинства пользователей, но у меня уже был проект, в котором вывод не был принят пользователями без этих исправлений.
Дискретные функции или операторы (например, по модулю)
Когда задействованы дискретные операторы или функции, могут потребоваться дополнительные корректировки, чтобы убедиться, что выходные данные соответствуют ожидаемым. Округление и добавление небольших исправлений перед округлением не может решить проблему.
Может потребоваться специальная проверка / исправление промежуточных результатов расчета сразу после применения дискретной функции или оператора.
Для конкретного случая (оператор по модулю) см. Мой ответ на вопрос: Почему оператор модуля возвращает дробное число в javascript?
Лучше избегать проблем
Часто более эффективно избегать этих проблем, используя типы данных (целочисленные или с фиксированной запятой) для таких вычислений, которые могут хранить ожидаемый ввод без ошибок округления.
Примером этого является то, что вы никогда не должны использовать значения с плавающей запятой для финансовых расчетов.