共用方式為


疑難排解資料類型 (Visual Basic)

本頁列出對內建資料類型執行作業時可能發生的一些常見問題。

Floating-Point 運算式不會相等

當您使用浮點數 (單一資料類型雙精度資料類型) 時,請記住它們會儲存為二進位分數。 這意味著它們不能包含任何非二進制分數的量的精確表示(形式為 k / (2 ^ n),其中 k 和 n 是整數)。 例如,0.5 (= 1/2) 和 0.3125 (= 5/16) 可以作為精確值,而 0.2 (= 1/5) 和 0.3 (= 3/10) 只能是近似值。

由於這種不精確性,當您對浮點值進行操作時,您無法依賴確切的結果。 特別是,理論上相等的兩個值可能具有略有不同的表示法。

比較浮點數量
1、使用命名空間中System類別Math的方法計算Abs它們差異的絕對值。
2. 確定一個可接受的最大差異,這樣,如果兩個量的差異不大,您可以出於實際目的認為這兩個量是相等的。
3. 將差異的絕對值與可接受的差異進行比較。

下列範例示範兩個 Double 值的不正確和正確比較。

Dim oneThird As Double = 1.0 / 3.0
Dim pointThrees As Double = 0.333333333333333

' The following comparison does not indicate equality.
Dim exactlyEqual As Boolean = (oneThird = pointThrees)

' The following comparison indicates equality.
Dim closeEnough As Double = 0.000000000000001
Dim absoluteDifference As Double = Math.Abs(oneThird - pointThrees)
Dim practicallyEqual As Boolean = (absoluteDifference < closeEnough)

MsgBox("1.0 / 3.0 is represented as " & oneThird.ToString("G17") &
    vbCrLf & "0.333333333333333 is represented as " &
    pointThrees.ToString("G17") &
    vbCrLf & "Exact comparison generates " & CStr(exactlyEqual) &
    vbCrLf & "Acceptable difference comparison generates " &
    CStr(practicallyEqual))

上一個範例使用 ToString 結構的方法 Double ,以便它可以指定比關鍵字使用的更好的 CStr 精確度。 預設值為 15 位數,但「G17」格式將其擴展為 17 位數。

Mod 運算子未傳回準確的結果

由於浮點儲存的不精確性,當至少其中一個運算元是浮點時, Mod 運算子 可能會傳回非預期的結果。

十進位資料類型不使用浮點表示法。 許多不精確 SingleDoubleDecimal 的數字和精確的數字(例如 0.2 和 0.3)。 雖然算術 Decimal 比浮點慢,但為了達到更好的精度,降低效能可能是值得的。

尋找浮點量的整數餘數
1. 將變數宣告為 Decimal
2. 使用文字類型字元 D 強制文字 Decimal,以防其值對於資料類型來說 Long 太大。

下列範例示範浮點運算元的潛在不精確性。

Dim two As Double = 2.0
Dim zeroPointTwo As Double = 0.2
Dim quotient As Double = two / zeroPointTwo
Dim doubleRemainder As Double = two Mod zeroPointTwo

MsgBox("2.0 is represented as " & two.ToString("G17") &
    vbCrLf & "0.2 is represented as " & zeroPointTwo.ToString("G17") &
    vbCrLf & "2.0 / 0.2 generates " & quotient.ToString("G17") &
    vbCrLf & "2.0 Mod 0.2 generates " &
    doubleRemainder.ToString("G17"))

Dim decimalRemainder As Decimal = 2D Mod 0.2D
MsgBox("2.0D Mod 0.2D generates " & CStr(decimalRemainder))

上一個範例使用 ToString 結構的方法 Double ,以便它可以指定比關鍵字使用的更好的 CStr 精確度。 預設值為 15 位數,但「G17」格式將其擴展為 17 位數。

因為 zeroPointTwoDouble,其 0.2 的值是無限重複的二進位分數,儲存值為 0.200000000000000001。 將 2.0 除以此數量得到 9.9999999999999999999999,餘數為 0.19999999999999999999。

在 的 decimalRemainder運算式中,文字類型字元 D 會強制兩個運算元都為 Decimal,而 0.2 具有精確的表示法。 因此, Mod 運算子會產生 0.0 的預期餘數。

請注意,僅宣告 decimalRemainderDecimal是不夠的。 您也必須強制文字 , Decimal否則它們預設會使用 Double ,並 decimalRemainder 接收與 相同的 doubleRemainder不準確值。

布林類型無法正確轉換為數值類型

布林資料類型 值不會儲存為數字,且儲存的值也不等同於數字。 為了與舊版相容,Visual Basic 提供轉換關鍵字 (CType 運算子CBoolCInt等) 來在數值類型之間 Boolean 進行轉換。 不過,其他語言有時會以不同的方式執行這些轉換,就像 .NET Framework 方法一樣。

您永遠不應該編寫依賴 和 FalseTrue對等數值的程式碼。 盡可能,您應該將變數的 Boolean 使用限制為設計變數的邏輯值。 如果您必須混合 Boolean 數值和數值,請確定您瞭解所選取的轉換方法。

Visual Basic 中的轉換

當您使用 CType 或 轉換關鍵字將數值資料類型Boolean轉換為 時,0 會變成 False ,而所有其他值都會變成 TrueCBool 。 當您使用轉換關鍵字將值轉換為 Boolean 數值類型時,會 False 變成 0 並 True 變成 -1。

框架中的轉換

ToInt32命名空間中System類別Convert的方法會True轉換為 +1。

如果您必須將值轉換為 Boolean 數值資料類型,請小心您使用的轉換方法。

字元常量產生編譯器錯誤

在沒有任何類型字元的情況下,Visual Basic 會假設常值的預設資料類型。 字元常值的預設類型 (以引號 (" ") 括住) — 是 String

String資料類型不會擴大為 Char 資料類型。 這表示如果您想要將文字指派給 Char 變數,則必須進行縮小轉換,或強制將文字轉換為 Char 類型。

建立要指派給變數或常數的 Char 文字
1. 將變數或常數宣告為 Char
2. 將字元值括在引號 ()" " 中。
3. 在右雙引號後面加上文字類型字元 C ,以強制文字為 Char。 如果類型檢查開關(Option Strict Statement)是 On,則這是必要的,並且在任何情況下都是可取的。

下列範例示範將常值 Char 指派給變數的不成功和成功。

Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"c
' The following statement succeeds because it converts String to Char.
charVar = CChar("Z")

使用縮小轉換總是有風險,因為它們可能會在執行時期失敗。 例如,如果值包含多個字元,則StringString 到 的Char轉換可能會失敗。 因此,最好使用類型字元進行 C 程式設計。

字串轉換在執行階段失敗

字串資料類型參與的範圍很小的擴大轉換。 String 僅加寬到自身 和 Object,並且只有 CharChar() (數 Char 組)加寬到 String。 這是因為 String 變數和常數可以包含其他資料類型無法包含的值。

當類型檢查開關 (Option Strict 陳述式) 為 On時,編譯器不允許所有隱含的縮小轉換。 這包括那些涉及 String. 您的程式碼仍然可以使用轉換關鍵字,例如 CStr和 CType 運算子,以指示 .NET Framework 嘗試轉換。

備註

對於從集合中的 For Each…Next 元素轉換到迴圈控制變數,會抑制縮小轉換錯誤。 如需詳細資訊和範例,請參閱針對 每個...Next 陳述式

縮小轉換保護

縮小轉換的缺點是它們可能會在執行時期失敗。 例如,如果變數 String 包含「True」或「False」以外的任何內容,則無法將其轉換為 Boolean。 如果包含標點符號字元,則轉換為任何數值類型都會失敗。 除非您知道變數 String 一律會保留目的地類型可以接受的值,否則不應嘗試轉換。

如果您必須從轉換成 String 其他資料類型,最安全的程序是將嘗試的轉換包含在 Try...捉。。。最後聲明。 這可讓您處理執行階段失敗。

字元陣列

單一 Char 和元素陣 Char 列都會加寬為 String。 但是, String 不會擴大到 Char()。 若要將值轉換為StringChar陣列,可以使用ToCharArray類別的方法System.String

無意義的價值觀

一般來說, String 值在其他資料類型中沒有意義,轉換是高度人為和危險的。 盡可能,您應該將變數的 String 使用限制在設計變數的字元序列上。 您絕對不應該撰寫依賴其他類型中對等值的程式碼。

另請參閱