iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 13
1
Modern Web

C#與ASP.Net入門-我要成為工程師!!系列 第 13

Day13-C#的無條件進入、無條件捨去、跟你想的不一樣的四捨五入!(補充:怎麼對小數點後某位數作無條件捨去或是無條件進入?)

還記得這一篇有提到賣場折扣這件事嗎?其實以前待的公司在辦某些活動為了避免遇到客怨,金額有小數點都是無條件捨去呵呵,於是乎我也來研究了一下C#的四捨五入、無條件進入、無條件捨去狀況怎麼辦~

此篇會分成正數與負數,並使用方法Math.Ceiling()、Math.Floor()、Math.Round()、Convert.ToInt32(Double)、Math.Truncate以及(int)轉型

首先,先來看看Math.Ceiling()和Math.Floor()在MSDN的定義

**Math.Ceiling()**方法:傳回大於或等於指定數字的最小整數值。
**Math.Floor()**方法:傳回小於或等於指定數字的最大整數值。

也就是說,把欲轉換的值包起來的兩個整數中,ceiling取大的那個整數,floor取小的那個整數

由於是比較把值包起來的兩個整數的大小,Math.Ceiling()和Math.Floor()正數與負數的用法剛剛好相反~

[無條件進入]

正數

使用**Math.Ceiling()**方法

double aa = Math.Ceiling(6.4);//輸出7
double aa1= Math.Ceiling(6.5);//輸出7
double aa2 = Math.Ceiling(6.9);//輸出7

負數

使用**Math.Floor()**方法

double aa3 = Math.Floor(-6.4);//輸出-7
double aa4 = Math.Floor(-6.5);//輸出-7
double aa5 = Math.Floor(-6.9);//輸出-7

[無條件捨去]

正數

  • 方法一
    使用**Math.Floor()**方法
double aa = Math.Floor(6.4);//輸出6
double aa1 = Math.Floor(6.5);//輸出6
double aa2 = Math.Floor(6.9);//輸出6
  • 方法二
    取整數值的話,可以使用int直接轉型
int aa = (int)6.4;//輸出6
int aa1 = (int)6.5;//輸出6
int aa2 = (int)6.9;//輸出6
  • 方法三
    使用Math.Truncate()方法:計算數字的整數部分。換言之,捨棄所有小數點後的數字。
Console.WriteLine(Math.Truncate(2.1));//輸出2
Console.WriteLine(Math.Truncate(3.8));//輸出3

負數

  • 方法一
    使用**Math.Ceiling()**方法
double aa3 = Math.Ceiling(-6.4);//輸出-6
double aa4 = Math.Ceiling(-6.5);//輸出-6
double aa5 = Math.Ceiling(-6.9);//輸出-6
  • 方法二
    取整數值的話,可以使用int直接轉型
int aa3 = (int)-6.4;//輸出-6
int aa4 = (int)-6.5;//輸出-6
int aa5 = (int)-6.9;//輸出-6
  • 方法三
    使用Math.Truncate()方法:計算數字的整數部分。換言之,捨棄所有小數點後的數字。
Console.WriteLine(Math.Truncate(-2.1));//輸出-2
Console.WriteLine(Math.Truncate(-3.8));//輸出-3

[四捨五入]

首先要介紹的是你不常聽到的奇進偶捨(也有人稱為四捨六入五成雙)

奇進偶捨,是一種計數保留法,是一種數值簡化規則。從統計學的角度,「奇進偶捨」比「四捨五入」更為精確:在大量運算時,因為捨入後的結果有的變大,有的變小,更使捨入後的結果誤差均值趨於零。而不是像四捨五入那樣逢五就進位,導致結果偏向大數,使得誤差產生積累進而產生系統誤差。「奇進偶捨」使測量結果受到捨入誤差的影響降到最低。(維基百科)

MSDN在使用四捨五入這個詞的時候,其實是採用奇進偶捨的方式,與我們平常認知的四捨五入有一點點差異。
牽扯到進位與精確度的部分,可以參考這篇官方說明中間部分
但老實說就算它用的都是中文我還是看不懂呵呵

而奇進偶捨的規則是:
1.尾數1~4會捨去,6~9會進位(與四捨五入相同)。如:4.4取整數會變成4,4.6取整數會變成5
2.如果尾數是5,後方有其他數字,則5會進位(與四捨五入相同)。如:4.501取整數會變成5
3.如果尾數是5,後方也沒有其他數字,進位與否則看尾數5的前一位是誰,奇數則進位,偶數則捨去。如:4.5取整數會變成4,5.5取整數會變成6

於是,遇到四捨五入的議題時,不分正負數,你有幾種選擇可以使用

  • Convert.ToInt32()(要四捨五入到整數的時候)
    採奇進偶捨
//正數
int aa3 = Convert.ToInt32(6.4);//輸出6
int aa4 = Convert.ToInt32(6.5);//輸出6<--沒有進位
int aa5 = Convert.ToInt32(6.9);//輸出7
int aa7 = Convert.ToInt32(7.4);//輸出7
int aa8 = Convert.ToInt32(7.5);//輸出8<--有進位
int aa9 = Convert.ToInt32(7.9);//輸出8
//負數
int aa3 = Convert.ToInt32(-6.4);//輸出-6
int aa4 = Convert.ToInt32(-6.5);//輸出-6<--沒有進位
int aa5 = Convert.ToInt32(-6.9);//輸出-7
int aa7 = Convert.ToInt32(-7.4);//輸出-7
int aa8 = Convert.ToInt32(-7.5);//輸出-8<--有進位
int aa9 = Convert.ToInt32(-7.9);//輸出-8
  • Math.Round(Double,小數點第幾位,取的方法)
    宣告須為double,取的方法有兩種:
    MidpointRounding.AwayFromZero→等同現實生活的四捨五入(向外捨入零)
    MidpointRounding.ToEven→四捨六入五成雙(預設)
//正數
double aa3 = Math.Round(6.4);//輸出6
double aa4 = Math.Round(6.5);//輸出6<--沒有進位
double aa5 = Math.Round(6.9);//輸出7
double aa7 = Math.Round(7.4);//輸出7
double aa8 = Math.Round(7.5);//輸出8<--有進位
double aa9 = Math.Round(7.9);//輸出8
//負數
double aa3 = Math.Round(-6.4);//輸出-6
double aa4 = Math.Round(-6.5);//輸出-6<--沒有進位
double aa5 = Math.Round(-6.9);//輸出-7
double aa7 = Math.Round(-7.4);//輸出-7
double aa8 = Math.Round(-7.5);//輸出-8<--有進位
double aa9 = Math.Round(-7.9);//輸出-8

//四捨五入到指定小數位,並使用MidpointRounding.AwayFromZero方法
double aa3 = Math.Round(-6.45,1, MidpointRounding.AwayFromZero);
//四捨五入到小數第一位,採MidpointRounding.AwayFromZero,輸出-6.5
double aa4 = Math.Round(-6.55,1, MidpointRounding.AwayFromZero);
//四捨五入到小數第一位,採MidpointRounding.AwayFromZero,輸出-6.6
  • 使用String.Format

如果只是要show出四捨五入,也可以使用String.Format

Console.WriteLine(2.5.ToString("0"));//輸出只有一個位數的2.5
Console.WriteLine(3.5.ToString("0"));//輸出只有一個位數的3.5


延伸:那我要怎麼對小數點後兩位作無條件捨去或是無條件進入?

有一個數為6.54569,小數點後兩位作無條件捨去。

double x = 6.54569;
x = x * 100;//x=654.569
x = Math.Floor(x);//無條件捨去
x = x / 100;//把100除回來
Console.WriteLine(x);

==============================================================================

參考資料

MSDN-Math Class
維基百科-奇進偶捨


上一篇
Day12-C#的條件判斷- switch
下一篇
Day14-C#-輸出格式好幫手String.Format/有$好辦事=ˇ=
系列文
C#與ASP.Net入門-我要成為工程師!!31

尚未有邦友留言

立即登入留言