js在进行小数点的四则运算,结果可能会出现有偏差,看以下几个例子:
console.log(0.1 + 0.2); //0.30000000000000004
console.log(-0.09999999 - 0.00000001); //-0.09999999999999999
console.log(0.012345 * 0.000001); //1.2344999999999999e-8
console.log(0.000001 / 0.0001); //0.009999999999999998
所以我们得做一下封装处理,看一下代码:
function Handle(num,type,num2) {
if(num2) {
this.total = num2;
}
let wrapObj = {
'+': this.add,
'-': this.sub,
'*': this.mul,
'/': this.div
}
wrapObj[type].call(this,num);
}
Handle.prototype.add = function(num) { //加法
let getArr = this.getDoubleVal(num);
this.total = (getArr[0] + getArr[1]) / (Math.pow(10,Number(getArr[2])));
return this;
}
Handle.prototype.sub = function(num) { //减法
let getArr = this.getDoubleVal(num);
this.total = (getArr[0] - getArr[1]) / (Math.pow(10,Number(getArr[2])));
return this;
}
Handle.prototype.mul = function(num) { //乘法
let getArr = this.getDoubleVal(num);
this.total = (getArr[0] * getArr[1]) / (Math.pow(10,getArr[2] *getArr[2]));
return this;
}
Handle.prototype.div = function(num) { //除法
let getArr = this.getDoubleVal(num);
this.total = (getArr[0]/getArr[1]);
return this;
}
Handle.prototype.judgeLeng = function(val) {
val = String(val);
let valArr = val.split('.');
if(valArr.length > 1) {
return valArr[1].length;
}else {
return 0;
}
}
Handle.prototype.getDoubleVal = function(num) {
let firL = this.judgeLeng(this.total);
let secL = this.judgeLeng(num);
let del = firL - secL >= 0 ? firL : secL;
let firVal = this.total * Math.pow(10,del);
let selVal = num * Math.pow(10,del);
return [firVal,selVal,del];
}
Handle.prototype.result = function(val) { //获取结果
return this.total;
}
以上我们封装了一个构造函数Handle,其中的思路就是先把小数放大成整数,进行四则运算,然后把结果根据放大的关系比例缩回去,得到正确的结果。通过封装,我们可以使用链式的方式进行四则运算,我们来使用下,
栗子一:
做一个 0.1 + 0.2
的加法运算
new Handle(0.1,"+",0.2).result(); //0.3
栗子二:
(0.1 + 0.2) *100/10
的运算:
new Handle(0.1,"+",0.2).mul(100).div(10).result(); //30