Последний блог глубоко проанализировал причины 0.1+0.2 === 0.300000000000000004.
В этом блоге в основном будут представлены примеры кода нескольких библиотек Javascript, которые решают проблему потери десятичной точности, а также примеры кода простых нативных методов EcmaScript.
1. Часть библиотеки классов
math.js
math.js — обширная математическая библиотека для JavaScript и Node.js. Поддерживает операции с такими типами данных, как числа, большие числа, комплексные числа, дроби, единицы измерения и матрицы.
Официальный сайт:mathjs.org/Гитхаб:GitHub.com/Джо сказал Чонгук/нет…
0.1 + 0.2 === 0.3 Код реализации:
var math = require('mathjs')
console.log(math.add(0.1,0.2))//0.30000000000000004
console.log(math.format((math.add(math.bignumber(0.1),math.bignumber(0.2)))))//'0.3'
decimal.js
Предоставляет JavaScript числовое значение произвольной точности десятичного типа.
Официальный сайт:mikemcl.github.io/decimal.js/
Гитхаб:GitHub.com/Mike MC приходит/получается…
var Decimal = require('decimal.js')
x = new Decimal(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'
bignumber.js
Библиотека JavaScript для арифметики произвольной точности.
Официальный сайт:Mick Friction.GitHub.IO/big number.Just…
Гитхаб:GitHub.com/Mike MC приближается/закрывается…
var BigNumber = require("bignumber.js")
x = new BigNumber(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'
big.js
Небольшая и быстрая библиотека JavaScript для десятичной арифметики произвольной точности. Официальный сайт:mikemcl.github.io/big.js/Гитхаб:GitHub.com/Mike MC приближается/закрывается…
var Big = require("big.js")
x = new Big(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'
Следует отметить, что вывод 0.3 библиотекой классов имеет тип String, поэтому, если вы хотите сохранить его как числовой тип, вы можете использовать метод parseFloat().
Еще один момент, на который следует обратить внимание, это то, что при локальном тестировании npm i mathjs -g require также является require('mathjs'), а не math.js с точками, потому чтоjosdejongЭтот человек при создании проекта носит имя mathjs, в то же время у него есть вышеупомянутые decimal.js, bignumber.js и big.js.MikeMcl, в названии проекта стоит точка, поэтому при установке и импорте оно имеет вид xxx.js.
Как выбирать между этими тремя библиотеками классов, также необходимо анализировать в зависимости от конкретной ситуации, поэтому я не буду здесь вдаваться в подробности.
Наконец, научите вас веб-сайту для прямого онлайн-тестирования,npm.runkit.com, подпуть введите Node.js, который вы хотите протестировать.имя пакета, вы можете реализовать API в пакете онлайн-тестирования. Например: math.js:npm.runkit.com/mathjsбольшие.js:npm.runkit.com/big.js
Во-вторых, оригинальный метод
Библиотека классов на самом деле очень мощная Наш расчет 0,1 + 0,2 — это только верхушка айсберга Так как же использовать собственный код EcmaScript, чтобы применить его к простым сценариям задач?
Здесь используется метод Number.prototype.toFixed().
арифметика с плавающей запятой
метод toFixed()
Существует множество решений для операций с числами с плавающей запятой.Вот часто используемое решение.Перед тем, как судить о результате операций с числами с плавающей запятой, точность результата вычисления уменьшается, потому что процесс уменьшения точности всегда будет автоматически округляться.
Метод toFixed() форматирует число с использованием записи с фиксированной точкой, округляя результат. Синтаксис:
Код JavaScript: numobj.tofixed (цифры) Цифры параметров представляют количество цифр после десятичной точки; от 0 до 20 (включительно) среда внедрения может поддерживать более широкий диапазон. Если этот параметр опущен, по умолчанию по умолчанию по умолчанию 0.
Возвращает строковое представление числа, которое не использует экспоненциальное представление, но содержит цифры после запятой. При необходимости число округляется, а дробная часть при необходимости дополняется нулями, чтобы дробная часть имела указанное количество цифр. Если число больше 1e+21, метод просто вызывает Number.prototype.toString() и возвращает строку в экспоненциальном формате.
Специальное примечание: toFixed() возвращает строковое представление числа.
В частности, вы можете просмотретьMDN, то мы можем решить проблему точности следующим образом:
Код JavaScript:
parseFloat((数学表达式).toFixed(digits)); // toFixed() 精度参数须在 0 与20 之间,建议传2。2是为了处理5/9这样的无限循环小数。
// 运行
parseFloat((0.1 + 0.2).toFixed(10))//结果为0.3
parseFloat((0.3 / 0.1).toFixed(10)) // 结果为 3
parseFloat((0.7 * 180).toFixed(10))//结果为126
parseFloat((1.0 - 0.9).toFixed(10)) // 结果为 0.1
parseFloat((9.7 * 100).toFixed(10)) // 结果为 970
parseFloat((2.22 + 0.1).toFixed(10)) // 结果为 2.32
Параметр точности среды браузера допускает значение от 0 до 100 бит (включая 100), а тестовая версия — Chrome62 (64-разрядная версия) и Firefox56 (32-разрядная версия). В среде Nodejs он может быть только от 0 до 20, а тестовая версия — v6.9.5.
Во-вторых, обсуждение совместимости браузера с Tofixed(), результаты, предоставленные MDN, все да, независимо от настольного терминала или мобильной стороны, то есть не беспокойтесь о проблемах совместимости с Tofixed() (IE8 мы не обсуждаем).
сторона рабочего стола:
мобильный терминал:
Thanks: Уууу. CSS88.com/archives/73… developer.Mozilla.org/this-cn/docs/…
Обновление 2019.7.28:
parseFloat((5/9).toFixed(10)) возвращает 0,5555555556. Поэтому более рекомендуемым подходом является parseFloat((5/9).toFixed(2)), который управляет десятичной дробью до 2 цифр.
Расчет денег является самым сложным, например, расчет юаней, на самом деле он очень точен, Юаньцзяо. Единица сантиметр очень мала, и в жизни встречается очень редко.
Я с нетерпением жду возможности пообщаться с вами и вместе добиться прогресса. Приглашаем вас присоединиться к созданной мной технической дискуссионной группе, тесно связанной с фронтенд-разработкой:
- Столбец SegmentFault:Будь хорошим фронтенд-инженером, пока ты еще молод
- Знать столбец:Будь хорошим фронтенд-инженером, пока ты еще молод
- Блог на гитхабе:личный блог 233, пока ты еще молод
- Публичный аккаунт WeChat: Dada Front-end/excellent_developers
Стремитесь стать отличным front-end инженером!