Как можно избежать ошибок с плавающей запятой при конвертации из источника валюты в десятичном формате в полностью веб-стеке javascript? - PullRequest
1 голос
/ 23 мая 2019

Недавно мне пришлось разрабатывать приложение для обработки денег, которое было бы полностью на javascript, express.js, REST apis, полном стеке js для узла / браузера. К сожалению, приложение обрабатывает различные пользовательские вычисления, такие как усреднение результатов. Конечно, при усреднении результатов в игру вступают сложение и деление с плавающей запятой. Таким образом, я бы получил значения, которые были выключены примерно на 0,12 (12 центов!).

Я понимаю рекомендуемые варианты для работы с поплавками в теории:

  • Рассчитать в целых числах
  • Круглый
  • Использовать десятичный тип данных где-нибудь еще

Подход с целыми числами для валюты - это хорошо, это имело бы смысл, но, к сожалению, если запросы поступают в десятичной форме, то все равно должны выполняться какие-то вычисления для первоначального преобразования чисел в целые числа, и вероятность ошибки все еще сохраняется.

Допустим, приходит запрос на добавление 44.67 в список значений в долларах. Было бы неплохо работать с ним в чистых целочисленных единицах, но чтобы попасть туда, сначала нужно умножить на 100, что, как я подозреваю, приводит к целому набору ошибок.

Так в javascript каков процесс обработки плавного преобразования между десятичными или долларовыми запросами и вычислениями, которые позволяют избежать ошибок с плавающей запятой?

В таком случае требуется ли база данных, а значения просто должны быть переданы в базу данных в виде строк? Или есть способ конвертировать "без потерь" в целые числа в JavaScript? Или есть какая-то другая техника при обращении с деньгами и требовании точности?

1 Ответ

1 голос
/ 23 мая 2019

Потенциальные источники ошибок в задаче, как описано в вопросе, включают:

  • Входные значения настолько велики, что не могут быть умножены на 100 и округлены до ближайшего целого числа без ошибок.(Для этого требуются входные значения около 10 13 или более, поэтому маловероятно, если данные не содержат триллионов долларов.)
  • Выполненные вычисления могут привести к таким большим значениям, что возникают ошибки округления.
  • «Пользовательские вычисления», упомянутые во входных данных, включают вещи, которые имеют ошибки округления, даже если значения являются маленькими целыми числами.Например, упоминается «усреднение», и среднее значение 1 цента, 1 цента и 2 центов не может быть вычислено в двоичной с плавающей запятой без ошибок округления, поскольку 4/3 не представимо.Кроме того, «пользовательские вычисления» могут включать в себя логарифмы, оценки вероятностных распределений, интегрирования и другую математику помимо элементарной арифметики.
  • В коде могут быть ошибки.

Так в [JavaScript] каков процесс обработки плавного преобразования между десятичными или долларовыми запросами и вычислениями, которые позволяют избежать ошибок с плавающей запятой?

Что касается первого, если x - это числопредставлены во входных символах в десятичном формате с максимум двумя цифрами после десятичной точки и не слишком велики (как указано выше), а x является результатом правильного преобразования этого ввода в JavaScript Number, а затем Math.round(100*x) - это ровно 100 x .Нет чистой ошибки округления.Источники любых ошибок вычислений находятся в другом месте.

...