1. 程式人生 > >javascript中toFixed()方法

javascript中toFixed()方法

以前一直以為toFixed方法就是四捨五入的,知道一個使用者反饋了金額計算的bug我才如夢初醒(虧了一毛錢),才仔細深究了下toFixed這個方法,唉,還是我不夠嚴謹啊,前車之鑑,大家勿走我的老路!

toFixed還不同的瀏覽器實現,在IE10及以上裡面是正常的四捨五入,但是別的瀏覽器裡面就不一樣了,它不是正常的四捨五入(等下重點說),比如:


var a = 1.335;
console.log(a.toFixed(2))
// IE         1.34
//chorme   1.33
其他的瀏覽器我沒去一一測試,所以如果大家用了其他瀏覽器的還是需要去實際測試一下,我這裡就說說javascript的toFixed()方法的四捨五入原理:
toFixed它是一個四捨六入五成雙的詭異的方法(也叫銀行家演算法),"四捨六入五成雙"含義:對於位數很多的近似數,當有效位數確定後,其後面多餘的數字應該捨去,只保留有效數字最末一位,這種修約(舍入)規則是“四捨六入五成雙”,也即“4舍6入5湊偶”這裡“四”是指≤4 時捨去,"六"是指≥6時進上,"五"指的是根據5後面的數字來定,當5後有數時,舍5入1;當5後無有效數字時,需要分兩種情況來講:①5前為奇數,舍5入1;②5前為偶數,舍5不進。(0是偶數) 


但是,經過我的測試發現,在chorme下面(最新版),並沒有完全遵守這個規則,尤其是5的後面沒有數字的時候,不是這麼判斷的,如下:


var b = 1.335
b.toFixed(2)
"1.33"
var b = 1.345
b.toFixed(2)
"1.34"
var b = 1.355
b.toFixed(2)
"1.35"
var b = 1.365
b.toFixed(2)
"1.36"
var b = 1.375
b.toFixed(2)
"1.38"
var b = 1.385
b.toFixed(2)
"1.39"
可以發現在chorme下沒有完全去遵循這個規律,或許它有自己的演算法,但是畢竟它沒有遵循通用的銀行家演算法,所以tofixed這個方法在涉及到金錢計算的業務中還是少用,
最好別用,否則可能會出大問題!

下面再再說說我自己的做法,就是根據精確位數來取小數點後的數,然後判斷精確位是大於4還是小於等於4,上程式碼吧,不說了:

我們的業務是最多精確到分,也就是兩位小數,最少就是取整,不留小數


function moneySwitch(money, precision){//precision是需要精確的位數,如百分位就是2
    var result = 0;
    //先進行一個千分位的四捨五入,保證3.0999這種情況在保留一位小數的時候能是對的,這一位可以這麼做沒什麼問題
    var money = parseFloat(money).toFixed(3);
    try{
        var int_part = money.split(".")[0], //小數點前的整數
        point_num = money.split(".")[1],//取小數點後面的小數
        precision_num = point_num[3-precision];
        if(precision_num>4){//五入的情況
            if(precision==1){
                point_num = parseInt(point_num)+10+"";
                if(point_num.length>3){//說明往整數位進1
                    int_part = parseInt(int_part)+1+"";
                    point_num = point_num[1]+point_num[2];
                }else{
                    point_num = point_num[0]+point_num[1];
                }
                result = parseFloat(int_part+"."+point_num);
            }else if(precision==2){
                point_num = parseInt(point_num)+100+"";
                if(point_num.length>3){//說明往整數位進1
                    int_part = parseInt(int_part)+1+"";
                    point_num = point_num[1];
                }else{
                    point_num = point_num[0];
                }
                result = parseFloat(int_part+"."+point_num);
            }else if(precision==3){
                int_part = parseInt(int_part)+1+"";
                point_num = 0;
            }
            result = parseFloat(int_part+"."+point_num);
        }else{//四舍的情況
            if(precision==1){
                point_num = point_num[0]+point_num[1];
            }else if(precision==2){
                point_num = point_num[0];
            }else if(precision==3){
                point_num = 0;
            }
            result = parseFloat(int_part+"."+point_num);
        } 
    }catch(e){
        return parseFloat(money).toFixed(2);//如果過程中有出錯就tofixed代替為解決
    }
    return result;
}

--------------------- 
作者:show_code 
來源:CSDN 
原文:https://blog.csdn.net/playboyanta123/article/details/77677645 
版權宣告:本文為博主原創文章,轉載請附上博文連結!