在很多程式裡都有四捨五入Round的功能,但其四捨五入的結果是否真如預期? 負數的四捨五入是什麼結果?以下用JavaScript / .Net / Oracle /MS SQL /Excel  這幾種語言或工具來看看,結果都是出乎預料之外...


 

正數的四捨五入大都多什麼問題,問題在於負數,負數要怎麼四捨五入? 


 

JavaScript


Math.round(-0.51) = -1


Math.round(-0.5) = 0 ç 竟然沒有進位!


Math.round(-0.49)=0


 


Math.round(0.51) = 1


Math.round(0.5) = 1


Math.round(0.49)=0


 


.Net


Math.round(-0.51)=-1


Math.round(-0.5) = 0 ç 竟然沒有進位!


Math.round(-0.49)=0


 


Math.round(0.51) = 1


Math.round(0.5) = 0 ç 負數沒進位就算了,正數也沒有進位!


Math.round(0.49)=0


 


Oracle


Select round(-0.51) from dual =-1


Select round(-0.5) from dual =-1


Select round(-0.49) from dual =0


 


Select round(0.51) from dual =1


Select round(0.5) from dual =1


Select round(0.49) from dual =0


 


MS Sql


Select top 1 round(-1.51,0) from testable =-2


Select top 1 round(-1.5,0) from testable =-2


Select top 1 round(-1.49,0) from testable =-1


 


Select top 1 round(1.51,0) from testable =2


Select top 1 round(1.5,0) from testable =2


Select top 1 round(1.49,0) from testable =1


: 這時有個怪現象,如果用0.X,會出現錯誤訊息.


錯誤訊息為 : 執行批次時發生錯誤。錯誤訊息為: 算術溢位。


因此,測試數據為1.51 / 1.5 / 1.49…çMS SQL拒算0.X的小數字?


 


Excel


Round(-0.51) = -1


Round(-0.5) = -1


Round(-0.49) = 0


 


Round(0.51) = 1


Round(0.5) = 1


Round(0.49) = 0


 


 


  看了以上的清單後,或許有些人會覺得,怎麼.Net的結果這麼的奇怪,跟我們所認知的四捨五入不同,其實它沒有錯哦,這些只是誤會,MSDN裡可以看到一點,它所遵循的是IEEE Standard 7544,這種捨入有時稱為捨入至最接近值。如果要捨入值為偶數,則捨去,如果為奇數,則進位,有看沒有懂哦,用下列幾個數字來解說一下.


 


0.5 è 0


*因為要捨入值為偶數0,所以捨去0.50


1.5 è 2


*因為要捨入值為奇數1,所以進位0.52


2.5 è 2


*因為要捨入值為偶數2,所以捨去0.52


3.5 è 4


*因為要捨入值為奇數3,所以進位0.54


 


這個就是所謂的四捨六入五成雙(Banker’s Rounding)~


 


那要怎麼做才能達到我們原本預期的四捨五入?


.Net 2.0以上的Math.round多了一個MidpointRounding的參數可以傳入.


MidpointRounding.ToEven [Banker’s Rounding]


MidpointRounding.AwayFromZero [這就是大家小學所熟悉的四捨五入]


用法 :


Math.round(0.5,0,MidpointRounding.AwayFromZero) = 1


 


 


參考 :


MSDN Math.Round 方法


Math.Round 方法 (Decimal, MidpointRounding)


 


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 jeffyeh 的頭像
    jeffyeh

    jeffyeh

    jeffyeh 發表在 痞客邦 留言(0) 人氣()