
在淘宝早期的订单体系中把订单号算作数字处理,后来随便订单号暴增,已经跨越了
9007199254740992,最终的解法是把订单号改成字符串处理。
要想解决大年夜数的问题你可以引用第三方库 bignumber.js,道理是把所稀有字算作字符串,从新实现了计算逻辑,缺点是机能比原生的差很多。所以原生支撑大年夜数就很有须要了,如今 TC39 已经有一个 Stage 3 的提案 proposal bigint,大年夜数问题有问彻调果断。
toPrecision vs toFixed
数据处理时,这两个函数很轻易混淆。它们的合营点是把数字转成字符串供展示应用。留意在计算的中心过程不要应用,只用于最终结不雅。
不合点就须要留意一下:
- toPrecision 是处理精度,精度是大年夜左至右第一个不为0的数开端数起。
- toFixed 是小数点后指定位数取整,大年夜小数点开端数起。
两者都能对多余数字做凑整处理,也有些人用 toFixed 来做四舍五入,但必定要知道它是有 Bug 的。
如:1.005.toFixed(2) 返回的是 1.00 而不是 1.01。
原因: 1.005 实际对应的数字是 1.00499999999999989,在四舍五入时全部被舍去!
解法:应用专业的四舍五入函数 Math.round() 来处理。但 Math.round(1.005 * 100) / 100 照样不可,因为 1.005 * 100 = 100.49999999999999。还须要把乘法和除法精度误差都解决后再应用 Math.round。可以应用后面介绍的 number-precision#round 办法来解决。
解决筹划
数据展示类
- parseFloat(1.4000000000000001.toPrecision(12)) === 1.4 // True
封装成办法就是:
- function strip(num, precision = 12) {
- return +parseFloat(num.toPrecision(precision));
- }
为什么选择 12 做为默认精度?这是一个经验的选择,一捌揭捉?12就能解决掉落大年夜部分0001和0009问题,并且大年夜部分情况下也够用了,如不雅你须要更精确可声调高。
数据运算类
【编辑推荐】
- 国内最火的 HTML、CSS、JavaScript 开源项目 Top 榜,你知若干?
- 深刻浅出妙用Javascript中apply、call、bind
- JavaScript中缺点精确处理方法,你用对了吗?
- JavaScript是真正的OOP说话吗?
- 前端要概绫屈?看我在 JS 里写 SQL
对于运算类操作,如 +-*/,就不克不及应用 toPrecision 了。精确的做法是把小数转成整数后再运算。以加法为例:
- /**
- * 精确加法
- */
- function add(num1, num2) {
- const num1Digits = (num1.toString().split('.')[1] || '').length;
- const num2Digits = (num2.toString().split('.')[1] || '').length;
- const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
- return (num1 * baseNum + num2 * baseNum) / baseNum;
- }
以上办法能实用于大年夜部分场景。碰到科学计数法如 2.3e+1(当数字精度大年夜于21时,数字会强迫转为科学计数法情势显示)时还须要特别处理一下。
能读到这里,解释你异常有耐烦,那我就放个福利吧。碰到浮点数误差问题时可以直接应用
https://github.com/dt-fe/number-precision
完美支撑浮点数的加减乘除、四舍五入等运算。异常小只有1K,远小于绝大年夜多半同类库(如Math.js、BigDecimal.js),100%测试全覆盖,代码可读性强,不妨在你的应用里用起来!
(图片由此生成 http://www.binaryconvert.com/convert_double.html)
参考
- What Every Programmer Should Know About Floating-Point Arithmetic
- Why Computers are Bad at Algebra | Infinite Series
- Is Your Model Susceptible to Floating-Point Errors?
- IEEE 754
回到最关怀的问题:若何解决浮点误差。起首,理论上用有限的空间来存储无穷的小数是弗成能包管精确的,但我们可以处理一下获得我们期望的结不雅。
推荐阅读
写在前面如不雅想要实现数据存储,并描述清跋扈内部处理流程,我们可以采取怎么样的日记处理体系架构呢?这里>>>详细阅读
本文标题:JavaScript浮点数陷阱及解法
地址:http://www.17bianji.com/lsqh/37934.html
1/2 1