zoukankan      html  css  js  c++  java
  • 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, r2, 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, Math.max(r1, 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, arg2) {
        var r1, r2, m, 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, Math.max(r1, r2));
        n = (r1 >= r2) ? r1 : r2;
        return ((arg1 * m - arg2 * m) / m).toFixed(n);
    }
    

    尾声

    如果你觉得我写的不错或者对你有帮助的话,
    能不能请我吃一包辣条,就一包就可以了。
    感谢~,我已经好久咩有吃辣条了!
    感谢感谢~
    
    作者:明月人倚楼
    出处:https://www.cnblogs.com/IwishIcould/

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!

    万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    支付宝
    微信
    本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    drop table 、delete table和truncate table的区别
    润乾报表 删除导出excel弹出框里的选项
    学习笔记: 委托解析和封装,事件及应用
    学习笔记: 特性Attribute详解,应用封装
    学习笔记: 反射应用、原理,完成扩展,emit动态代码
    学习笔记: 泛型应用、原理、协变逆变、泛型缓存
    jmeter4.x centos7部署笔记
    rabbitmq3.7.5 centos7 集群部署笔记
    rabbitmq3.8.3 centos7 安装笔记
    UVA-12436 Rip Van Winkle's Code (线段树区间更新)
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/15345873.html
Copyright © 2011-2022 走看看