天天看點

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);
}      
尾聲
如果你覺得我寫的不錯或者對你有幫助的話,
能不能請我吃一包辣條,就一包就可以了。
感謝~,我已經好久咩有吃辣條了!
感謝感謝~      

遇見問題,這是你成長的機會,如果你能夠解決,這就是收獲。

作者:​​晚來南風晚相識​​​

本文版權歸作者所有,歡迎轉載,未經作者同意須保留此段聲明,在文章頁面明顯位置給出原文連接配接

繼續閱讀