Как обрабатывать плавающие точки в калькуляторе JavaScript? - PullRequest
0 голосов
/ 23 сентября 2019

Почему это не дубликат этих замечательных статей SO?

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

Фон

Я пытаюсь создать калькулятор с TypeScript без каких-либо библиотек (например, Big.js) и без использования конкатенации строк во внутренней логике калькулятора.

Примеры

Когда пользователь хочет ввести число 8,5:

  • Нажата клавиша 8
  • .нажата десятичная клавиша
  • нажата клавиша 5

Математически я создаю это число на дисплее со следующим фрагментом:

8 + 5 * 0.1

Это работает, но еслиЯ продолжаю вниз, после десятичных разрядов, я сталкиваюсь с чем-то неожиданным:

8.5 + 5 * 0.01 // 8.55
8.55 + 5 * 0.001 // 8.555000000000001

Вопрос

Каков наилучший способ справиться с этим без преобразования числа в строку?Есть ли разумный способ наложить ограничение на точность калькулятора, чтобы он поддерживал точность только до стольких десятичных разрядов?

Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Самый простой способ получить значение Number, наиболее близкое к тому, что вводит пользователь, - это построить число в строке из нажатия клавиши пользователя, а затем преобразовать их с помощью String.toNumber().

Числа, такиепоскольку 8.55 или 8.555 не могут быть точно представлены в формате Number.Ближайшими значениями являются 8.550000000000000710542735760100185871124267578125 и 8.55499999999999971578290569595992565155029296875.Преобразование строк «8.55» и «8.555» с помощью .toNumber() должно привести к получению этих значений.

Поскольку это наиболее близкие представимые значения, ни один расчет или алгоритм не может привести к более близким значениям в Numberformat.

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

1 голос
/ 23 сентября 2019

Используйте .toFixed(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

или .toPrecision(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision в зависимости от ваших потребностей.

Обратите внимание, что вам не нужно преобразовывать все числавремя.Единственное место для конвертации - это для окончательного вывода на просмотр.В этом случае мы можем даже оставить его в строковом формате.

Это ответ на вопрос «как управлять с помощью» (как в описании).О «почему мы получаем такой результат» - первый комментарий дает отличный ответ.

...