數字取整或保留小數四舍五入的正確寫法


【JS篇】

使用toFixed是錯誤的!請看下面例子:

(0.05).toFixed(1)    //0.1
(0.15).toFixed(1)    //0.1
(0.25).toFixed(1)    //0.3
(0.35).toFixed(1)    //0.3
(0.45).toFixed(1)    //0.5
(0.55).toFixed(1)    //0.6
(0.65).toFixed(1)    //0.7
(0.75).toFixed(1)    //0.8
(0.85).toFixed(1)    //0.8
(0.95).toFixed(1)    //0.9

 

與C#不同的是,js中的Math.round是可以正確顯示四舍五入的整數

Math.round(0.5)    //1
Math.round(1.5)    //2
Math.round(2.5)    //3
Math.round(3.5)    //4
Math.round(4.5)    //5
Math.round(5.5)    //6
Math.round(6.5)    //7
Math.round(7.5)    //8
Math.round(8.5)    //9
Math.round(9.5)    //10

 

所以在js中,正確的四舍五入應該這樣寫:

Math.round(0.05 * 10) / 10    //0.1
Math.round(0.15 * 10) / 10    //0.2
Math.round(0.25 * 10) / 10    //0.3
Math.round(0.35 * 10) / 10    //0.4
Math.round(0.45 * 10) / 10    //0.5
Math.round(0.55 * 10) / 10    //0.6
Math.round(0.65 * 10) / 10    //0.7
Math.round(0.75 * 10) / 10    //0.8
Math.round(0.85 * 10) / 10    //0.9
Math.round(0.95 * 10) / 10    //1

 

如果需要強制保留小數位數,再加上toFixed就可以了

(Math.round(0.95 * 10) / 10).toFixed(1)    //1.0

 

為了方便使用,封裝一下:

//小數四舍五入,f精度范圍[0,10]
Number.prototype.numberRound = function (f) {
    return NumberRound(this, f);
}
String.prototype.numberRound = function (f) {
    return NumberRound(this, f);
}
function NumberRound(n, f) {
    n = parseFloat(n);
    f = (f == "" || isNaN(f)) ? 0 : (f > 10 ? 10 : parseInt(f));var x = Math.pow(10, f);
    return Math.round(n * x) / x;
}

 

所以,這樣用起來就更方便了:

(0.15).numberRound(1)        //0.2
"0.15".numberRound(1)        //0.2
"0.15".numberRound("")       //0      空,精度為0
"0.15".numberRound("abc")    //0      非數字,精度為0
"0.15".numberRound(10000)    //0.15   超出精度最大值,精度為10
    

 

如果非要保留位數,就再加一個toFixed就可以了

(0.095).numberRound(1).toFixed(2)    //0.10

 

【C#篇】

相比JS,疑似C#四舍五入的方法有很多,最廣泛使用的Convert.ToInt32是錯誤的!請看下面例子:

Convert.ToInt32(0.5)    //0
Convert.ToInt32(1.5)    //2
Convert.ToInt32(2.5)    //2
Convert.ToInt32(3.5)    //4
Convert.ToInt32(4.5)    //5
Convert.ToInt32(5.5)    //6
Convert.ToInt32(6.5)    //6
Convert.ToInt32(7.5)    //8
Convert.ToInt32(8.5)    //8
Convert.ToInt32(9.5)    //10

 

那么,我們熟悉的Math.Round呢?竟然結果和上面完全一樣!也是錯誤的。

但是,Math.Round后面有一個可選參數(MidpointRounding.AwayFromZero),加上以后就正確了:

Math.Round(0.5,MidpointRounding.AwayFromZero)    //1
Math.Round(1.5,MidpointRounding.AwayFromZero)    //2
Math.Round(2.5,MidpointRounding.AwayFromZero)    //3
Math.Round(3.5,MidpointRounding.AwayFromZero)    //4
Math.Round(4.5,MidpointRounding.AwayFromZero)    //5
Math.Round(5.5,MidpointRounding.AwayFromZero)    //6
Math.Round(6.5,MidpointRounding.AwayFromZero)    //7
Math.Round(7.5,MidpointRounding.AwayFromZero)    //8
Math.Round(8.5,MidpointRounding.AwayFromZero)    //9
Math.Round(9.5,MidpointRounding.AwayFromZero)    //10

 

然后,再用ToString()試試:

(0.05).ToString("0.0")    //0.1
(0.15).ToString("0.0")    //0.2
(0.25).ToString("0.0")    //0.3
(0.35).ToString("0.0")    //0.4
(0.45).ToString("0.0")    //0.5
(0.55).ToString("0.0")    //0.6
(0.65).ToString("0.0")    //0.7
(0.75).ToString("0.0")    //0.8
(0.85).ToString("0.0")    //0.9
(0.95).ToString("0.0")    //1.0

 

很好,接着試ToString("#0.0")ToString("f1")ToString("g1"),也是一樣的結果,都是正確的!

 

ToString("#0.0")ToString("0.0")是一樣的,但ToString("0.0")ToString("0.#")不一樣:前者保留多余的0,后者省略多余的0

f1表示精度為1位,自動補0;g1表示精度為1位,不會補0,所以在C#中,四舍五入其實很簡單,直接 ToString()就可以了:

(0.65).ToString("f1")        //0.7
(0.65).ToString("f3")        //0.650
(0.65).ToString("g3")        //0.65

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM