# vb.net Math.Round ToEven,AwayFromZero 小數點後四位為什麼輸出的結果與預期的不同

• ### 問題

• 但是下列程式碼輸出結果不如預期，是為什麼?

Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim s As Double
Dim r As Double
Dim re As Double
Dim ra As Double
For i As Integer = 0 To 3000 Step 1
s = i / 10000 + 0.00005
r = Math.Round(s, 4)
re = Math.Round(s, 4, MidpointRounding.ToEven)
ra = Math.Round(s, 4, MidpointRounding.AwayFromZero)
Debug.Print(s & " : " & r & IIf(r > s, ",O", ",X") & "," & re & IIf(re > s, ",O", ",X") & "," & ra & IIf(ra > s, ",O", ",X"))
Next
End Sub
End Class

輸出結果

0.00015 : 0.0002,O,0.0002,O,0.0002,O
0.00025 : 0.0002,X,0.0002,X,0.0003,O
0.00035 : 0.0004,O,0.0004,O,0.0004,O
0.00045 : 0.0004,X,0.0004,X,0.0005,O
0.00055 : 0.0006,O,0.0006,O,0.0006,O
0.00065 : 0.0006,X,0.0006,X,0.0007,O
0.00075 : 0.0008,O,0.0008,O,0.0008,O
0.00085 : 0.0008,X,0.0008,X,0.0009,O
0.00095 : 0.001,O,0.001,O,0.001,O
0.00105 : 0.001,X,0.001,X,0.0011,O
0.00115 : 0.0012,O,0.0012,O,0.0012,O
0.00125 : 0.0012,X,0.0012,X,0.0012,X<-這第三組為什麼沒進位
0.00135 : 0.0013,X,0.0013,X,0.0013,X<-奇數不是應該進位
0.00145 : 0.0014,X,0.0014,X,0.0014,X<-這第三組為什麼沒進位
0.00155 : 0.0016,O,0.0016,O,0.0016,O
0.00165 : 0.0016,X,0.0016,X,0.0017,O
0.00175 : 0.0017,X,0.0017,X,0.0017,X<-奇數不是應該進位
0.00185 : 0.0018,X,0.0018,X,0.0019,O
0.00195 : 0.002,O,0.002,O,0.002,O
0.00205 : 0.002,X,0.002,X,0.0021,O<-
0.00215 : 0.0022,O,0.0022,O,0.0022,O
0.00225 : 0.0023,O,0.0023,O,0.0023,O<-
0.00235 : 0.0024,O,0.0024,O,0.0024,O

-----------------------------------------------------------------------------------------

0.00015 : 0.0002,O,0.0002,O,0.0002,O
0.00115 : 0.0012,O,0.0012,O,0.0012,O
0.00215 : 0.0022,O,0.0022,O,0.0022,O
0.00315 : 0.0032,O,0.0032,O,0.0032,O
0.00415 : 0.0042,O,0.0042,O,0.0042,O
0.00515 : 0.0052,O,0.0052,O,0.0052,O
0.00615 : 0.0062,O,0.0062,O,0.0062,O
0.00715 : 0.0072,O,0.0072,O,0.0072,O

0.00815 : 0.0081,X,0.0081,X,0.0081,X <-為什麼這不進位

-----------------------------------------------------------------------------------------

 0.00025 : 0.0002,X,0.0002,X,0.0003,O 0.00125 : 0.0012,X,0.0012,X,0.0012,X 0.00225 : 0.0023,O,0.0023,O,0.0023,O 0.00325 : 0.0032,X,0.0032,X,0.0033,O 0.00425 : 0.0042,X,0.0042,X,0.0042,X 0.00525 : 0.0052,X,0.0052,X,0.0052,X 0.00625 : 0.0062,X,0.0062,X,0.0062,X 0.00725 : 0.0072,X,0.0072,X,0.0073,O 0.00825 : 0.0082,X,0.0082,X,0.0083,O 0.00925 : 0.0092,X,0.0092,X,0.0093,O 0.01025 : 0.0102,X,0.0102,X,0.0103,O 0.01125 : 0.0112,X,0.0112,X,0.0113,O

越後面越不知道規則在哪裡，有人可以解釋一下嗎?不太懂實際的結果為什麼會這樣!!

chansetter

一句話點醒我夢中人........
• 已編輯 2013年3月26日 上午 09:22
2013年3月26日 上午 09:08

### 解答

• 您好，

因為double是非精準數值，所以Round時，會先轉成10進位，然後再來處理Round。所以因此造成該進位而沒進位的狀況。

以上說明若有錯誤請指教，謝謝。
亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

• 已提議為解答 2013年3月26日 上午 09:19
• 已編輯 2013年3月26日 上午 09:21
• 已標示為解答 2013年3月26日 上午 09:21
2013年3月26日 上午 09:18

### 所有回覆

• 您好，

因為double是非精準數值，所以Round時，會先轉成10進位，然後再來處理Round。所以因此造成該進位而沒進位的狀況。

以上說明若有錯誤請指教，謝謝。
亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

• 已提議為解答 2013年3月26日 上午 09:19
• 已編輯 2013年3月26日 上午 09:21
• 已標示為解答 2013年3月26日 上午 09:21
2013年3月26日 上午 09:18
• 一句話點醒我夢中人........

非常感謝，原來這麼簡單，突然覺得我好蠢

chansetter

2013年3月26日 上午 09:23
• 是正确的：

规则：

1）保留N位，那么AwayFromZero规则：

1.1）如果后一位大于5，直接进位。

1.2）如果后一位小于5，直接舍去。

1.3）如果后一位=5，后面如果还有数字，直接进位1.

1.4）后一位=5，后面没有任何数字，那么前一位是偶数，直接舍去；否则进位凑成偶数。

0.00125，保留4位，那么按照这个规则：

第五位为5，后面没有任何数字，且第四位为偶数，直接舍去（0.0012）。

我用控制台运行，完全正确。

```Module Module1
Sub Main()
Dim s As Double
Dim r As Double
Dim re As Double
Dim ra As Double
For i As Integer = 0 To 100
s = i / 10000 + 0.00005
r = Math.Round(s, 4)
re = Math.Round(s, 4, MidpointRounding.ToEven)
ra = Math.Round(s, 4, MidpointRounding.AwayFromZero)
Console.WriteLine(s & " : " & r & IIf(r > s, ",O", ",X") & "," & re & IIf(re > s, ",O", ",X") & "," & ra & IIf(ra > s, ",O", ",X"))
Next
End Sub
End Module```