js计算精度不准问题(浮点数误差,大数误差)

js计算常见问题:

0.1+0.04  // 0.15000000000000002
1-0.9     // 0.09999999999999998
0.1*0.2   // 0.020000000000000004
0.14/10   // 0.014000000000000002
1.335.toFixed(2)  // 1.33
Math.round(-2.5)  // -2
Math.round(-2.51) // -3
9999999999999999// 10000000000000000

//显然这些都不是我们想要的

含有小数位的计算
0.1+0.04 = ?
计算时,0.1和0.04都需要先转换成二进制,然后进行二进制的相加,相加后的结果再转换成十进制才得出这个结果:0.15000000000000002
js最多能表示的精度是16位(小数后16位),加上省略的一位,最多能表示的数为2^53=9007199254740992。超过的用toPrecison(16)做处理,用toFixed(16)会有一些问题
如:1.335.toFixed(2) // 1.33

Number位数
Number类型最大可以表示的数是:2^1023。但在js中常用的数范围是(-2^53, 2^53),超过这个部分的数越往外就越不精确。即超过16位的就要另行处理了

至于Math.round(),MDN给出的描述:如果参数的小数部分大于0.5,则舍如到相邻的绝对值更大的整数。如果参数的小数部分小于0.5,则舍入到相邻的在正无穷方向上的整数。注意,与其他语言的round函数不同,Math.round()并不总是舍入到远离零的方向(尤其在负数的小数部分恰好等于0.5的情况下)

大神原理分析https://github.com/camsong/blog/issues/9

实用方法 :化为整数处理浮点数精度不准的问题
1、大佬原文方法https://blog.csdn.net/m0_37793545/article/details/79196311

Number.prototype.add = function(arg){          //加法
    var r1,r2,m;   
    try{r1=this.toString().split(".")[1].length}catch(e){r1=0}   
    try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}   
    m=Math.pow(10,Math.max(r1,r2))   
    return (this*m+arg*m)/m   
}     
   
Number.prototype.sub = function (arg){        //减法
    return this.add(-arg);   
}   

Number.prototype.mul = function (arg){        //乘法
    var m=0,s1=this.toString(),s2=arg.toString();   
    try{m+=s1.split(".")[1].length}catch(e){}   
    try{m+=s2.split(".")[1].length}catch(e){}   
    return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)   
}  

Number.prototype.div = function (arg){       //除法   
    var t1=0,t2=0,r1,r2;   
    try{t1=this.toString().split(".")[1].length}catch(e){}   
    try{t2=arg.toString().split(".")[1].length}catch(e){}   
    with(Math){   
        r1=Number(this.toString().replace(".",""))   
        r2=Number(arg.toString().replace(".",""))   
        return (r1/r2)*pow(10,t2-t1);   
    }   
} 

2、成熟的第三方库
math.js (百度math.js npm)
Math.js是一个用于JavaScript和Node.js的扩展数学库。它具有支持符号计算的灵活表达式解析器,大量内置函数和常量,并提供了集成的解决方案来处理不同的数据类型,例如数字,大数,复数,分数,单位和矩阵。强大且易于使用。

cdn:https://mathjs.org/download.html
npm:
npm install mathjs
引入:import * as math from "mathjs"
调用方法:
函数调用法:math.add(math.sqrt(4), 2)
表达式法: math.eval('sqrt(4) + 2')
链接操作法:math.chain(4).sqrt().add(2)
常用方法:
math.sqrt(4) 开方
math.add( ) 加
math.subtract( )减
math.divide( ) 除
math.multiply( )乘

bigNumber.js
big.js

发布了14 篇原创文章 · 获赞 10 · 访问量 1411

猜你喜欢

转载自blog.csdn.net/weixin_44708870/article/details/102932481