js加减乘除运算出现精度丢失

做乘法运算出现精度丢失

let aa= 2106.49 
console.log( aa*10000 ) //21064899.999999996
console.log( Math.round(aa*10000) ) //21064900

需求

因为输入的数字最多保留两位小数
当时想的是乘一个10000;【将元转化为万元】
是不会出现精度丢失这样的情况的
结果这填写金额的时候
啪啪打脸了,竟然出现了精度丢失的情况

关于Math.round的讲解

// 实际上,Math.round()方法四舍五入是不准确的哈【对正数来说正确】
// ,Math.round()方法四舍五入【对负数是不正确的】 
注意-1.5=-1;  [-1.6,-1.7,-1.8,-1.9]=2
还有需要注意的点是 Math.round()是一个整数
不会出现aaa.00,bb.0这样的情况

console.log(Math.round(1.0));  //1
console.log( Math.round(1.4)) //1
console.log( Math.round(1.5)); //2
console.log( Math.round(-1.0));//-1
console.log(Math.round(-1.4)); //-1
console.log(Math.round(-1.5)) ; //-1
console.log(Math.round(-1.6)) //-2
console.log(Math.round(-1.7)) //-2

整数的Math.round()是整数本省;
我使用
Math.round(aa*10000)来处理精度丢失是没有问题的
因为 Math.round()的是整数本身

使用Math.round的返回值有哪些

console.log( Math.round('1.X5')); //NaN
console.log( Math.round(null));//0
console.log(Math.round('0')); //0
console.log(Math.round('NaN')) ; //NaN
console.log(Math.round(undefined)) //NaN
console.log(Math.round('1.2121')) //1
console.log( Math.round('1.9')); //NaN

通过上面这个例子,我们发现 Math.round返回值有
NaN 和数字类型
null返回的是0;因为null表示的写了一个变量没有赋值就是null
如果你使用 Math.round是一个数字类型的字符串也是没有问题的,它仍然可以正确返回来

除法

function accDiv(arg1,arg2) {
    var t1 = 0,t2 = 0,r1,r2;
    try {
        t1 = arg1.toString().split(".")[1].length
    } catch (e) {}
    try {
        t2 = arg2.toString().split(".")[1].length
    } catch (e) {}
    with(Math) {
        r1 = Number(arg1.toString().replace(".",""))
        r2 = Number(arg2.toString().replace(".",""))
        return accMul((r1 / r2),pow(10,t2 - t1));
    }
}

乘法

function accMul(arg1,arg2) {
    var m = 0,s1 = arg1.toString(),s2 = arg2.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)
}

加法

function accAdd(arg1,arg2) {
    var r1,r2,m;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10,Math.max(r1,r2))
    return (arg1 * m + arg2 * m) / m
}
上面这个版本在在有些数字相加是会出问题的

改成下面的版本
function addd(arg1,arg2) {
	arg1 = arg1?arg1:0
	arg2 = arg2?arg2:0
	let r1,m,c;
	try {
		r1 = arg1.toString().split(".")[1].length;
	}
	catch (e) {
		r1 = 0;
	}
	try {
		r2 = arg2.toString().split(".")[1].length;
	}
	catch (e) {
		r2 = 0;
	}
	c = Math.abs(r1 - r2);
	m = Math.pow(10,r2));
	if (c > 0) {
		let cm = Math.pow(10,c);
		if (r1 > r2) {
			arg1 = Number(arg1.toString().replace(".",""));
			arg2 = Number(arg2.toString().replace(".","")) * cm;
		} else {
			arg1 = Number(arg1.toString().replace(".","")) * cm;
			arg2 = Number(arg2.toString().replace(".",""));
		}
	} else {
		arg1 = Number(arg1.toString().replace(".",""));
		arg2 = Number(arg2.toString().replace(".",""));
	}
	return (arg1 + arg2) / m;
}
console.log("xx",addd(10219.63,120.56))

减法

function Subtr(arg1,n;
    try {
        r1 = arg1.toString().split(".")[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split(".")[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10,r2));
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

尾声

如果你觉得我写的不错或者对你有帮助的话,
能不能请我吃一包辣条,就一包就可以了。
感谢~,我已经好久咩有吃辣条了!
感谢感谢~

相关文章

背景:计算机内部用补码表示二进制数。符号位1表示负数,0表...
大家好,我们现在来讲解关于加密方面的知识,说到加密我认为不...
相信大家在大学的《算法与数据结构》里面都学过快速排序(Qui...
加密在编程中的应用的是非常广泛的,尤其是在各种网络协议之...
前言我的目标是写一个非常详细的关于diff的干货,所以本文有...
对称加密算法 所有的对称加密都有一个共同的特点:加密和...