关于精度丢失问题

在做进销存时,遇到精度丢失的问题,就记一下

在JavaScript里,如果你认为0.1+0.2会等于0.3,你就错了,答案是0.30000000000000004

计算机的二进制实现和位数限制有些数无法有限表示

就像一些无理数不能有限表示,如 圆周率 3.1415926... 

此时只能模仿十进制进行四舍五入了,但是二进制只有 0 和 1 两个,于是变为 0 舍 1 入

这即是计算机中部分浮点数运算时出现误差,丢失精度的根本原因

那要怎么解决呢

思路的话是转变成整数去处理,之后再还原成小数

整数只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度

//加or减  减的话相当加一个负数
function add(n1, n2) {
    var s1, s2, m;
    try {
        s1 = n1.toString().split(".")[1].length;
    } catch (e) {
        s1 = 0;
    }
    try {
        s2 = n2.toString().split(".")[1].length;
    } catch (e) {
        s2 = 0;
    }
    m = Math.pow(10, Math.max(s1, s2));
    return (n1 * m + n2 * m) / m;
}
//
function ride(arg1, arg2) {
    if (arg1 == null || arg2 == null) {
        return null;
    }
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace(".", ""));
    n2 = Number(arg2.toString().replace(".", ""));
    return n1 * n2 / Math.pow(10, r1 + r2);
}
//
function except(arg1, arg2) {
    if (arg1 == null) {
        return null;
    }
    if (arg2 == null || arg2 == 0) {
        return null;
    }
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace(".", ""));
    n2 = Number(arg2.toString().replace(".", ""));
    return (n1 / n2) * Math.pow(10, r2 - r1);
}
posted @ 2021-09-16 14:35  Pavetr  阅读(435)  评论(0编辑  收藏  举报