第23天 [js] js精度计算问题

Posted Mr、DIVE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第23天 [js] js精度计算问题相关的知识,希望对你有一定的参考价值。

//[js] 0.1 + 0.2、0.1 + 0.3和0.1 * 0.2分别等于多少?并解释下为什么?
function newNew(){
    return parseFloat((0.1+0.2).toFixed(10)) ;
}

console.log(newNew());

补充下知识说不定就用到了呢,您说不是吗?

EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题!

 

js精度计算

参考技术A 在新公司的第一个项目是区块链相关的管理后台和交易所,其中就涉及了很多的计算问题。而JavaScript因为存在计算的精度问题,所以直接计算就可能会导致各种各样的bug,为了解决这个问题,就要使用BigNumber.js这个库。

至于为什么JavaScript会有精度问题呢,可以看 这里 。简单来说就是因为: JavaScript中所有的数字(包括整数和小数)都只有一种类型–Number。它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。它的优点是可以归一化处理整数和小数,节省储存空间。而实际计算的时候会转换成二进制计算再转成十进制。进制转换之后会很长,舍去一部分,计算再转回来,就有了精度误差。

BigNumber.js是一个用于任意精度计算的js库。可以在  官方文档  的console中测试使用。也可以通过npm install bignumber.js --save来安装。然后 import BigNumber from 'bignumber.js' 来引入使用。他的大概原理是将所有数字当做字符串,重新实现了计算逻辑。缺点是性能比原生的差很多。

现在 TC39 已经有一个 Stage 3 的提案 proposal bigint,大数问题有望彻底解决。在浏览器正式支持前,可以使用 Babel 7.0 来实现,它的内部是自动转换成 big-integer 来计算,要注意的是这样能保持精度但运算效率会降低。

具体用法可以参考以下资料:

官方文档

bignumber.js使用记录

BigNumber 讲解

就不再敖述了,下边随便写点常用的方法:

// 转为 bignumberconstx=newBigNumber('123456789.123456789');// 转为 普通数字x.toNumber()// 格式化(小数点)x.toFormat()// '123,456,789.123456789'x.toFormat(3)// '123,456,789.123'// 计算x.plus(0.1)// 加法x.minus(0.1)// 减法x.times(0.1)// 乘法x.div(0.1)// 除法x.mod(3)// 取模/取余// 比较大小x.eq(y)// isEqualTo 的简写,是否相等x.gt(y)// isGreaterThan 的简写,是否大于x.gte(y)// isGreaterThanOrEqualTo 的简写,是否大于等于x.lt(y)// isLessThan 的简写,是否小于x.lte(y)// isLessThanOrEqualTo 的简写,是否小于等于// 取非,改变数字的正负号x.negated()

以上是关于第23天 [js] js精度计算问题的主要内容,如果未能解决你的问题,请参考以下文章

js乘法精度计算代码 求解释

第23天:js-数据类型转换

关于js中小数运算丢失精度的处理办法

js浮点数精度丢失问题及如何解决js中浮点数计算不精准

JS浮点计算精度问题分析与解决

js 中Math.round()精度问题?急