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( )乘