数据类型疑难解答 (Visual Basic)
本页列出可能出现的常见问题,可以在对内部数据类型时的操作。
浮点表达式的比较结果不相等
在使用浮点数 (Single 数据类型 (Visual Basic) 和 Double 数据类型 (Visual Basic)),请确保其存储为二进制分数。 这意味着它们不能保存不是二进制分数任意数量的精确表示 k 和 n 是整数 () 的窗体 k / (2 ^ n) 。 例如, 0.5 (= 1/2) 和 0.3125 (= 5/16) 可保存为精确值,,而 0.2 (= 1/5) 和 0.3 (= 3/10) 可以是近似值。
因此,当您处理浮点值时,不精确性,不能依赖准确的结果。 具体而言,理论上相等的两个值具有略微不同的表示形式。
比较浮点数量 |
下面的示例演示两个 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))
上面的示例使用 Double 结构的 ToString 方法,使其比 CStr 使用关键字时可以指定更高的精度。 默认值为 15 位数,,但 “G17”格式将其扩展到 17 位数字。
Mod 运算符未返回准确的结果
由于浮点存储的不精确性,如果至少一个 Mod 运算符 (Visual Basic) 浮点操作数,时,可能会返回意外的结果。
Decimal 数据类型 (Visual Basic) 不使用浮点表示形式。 不精确在 Single 和 Double 的许多数字为确切在 Decimal (如 0.2 和 0.3)。 虽然算术运算速度上比 Decimal 在浮点,它可能会降低性能获得更高的精度。
找出浮点数量的整数余数 |
|
下面的示例演示了浮点操作数潜在的不精确性。
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))
上面的示例使用 Double 结构的 ToString 方法,使其比 CStr 使用关键字时可以指定更高的精度。 默认值为 15 位数,,但 “G17”格式将其扩展到 17 位数字。
由于 zeroPointTwo 是 Double,其 0.2 的值是一个无限重复与中存储的值的二进制分数为 0.20000000000000001。 将 2.0 除以此数量将得到 9.9999999999999995 余数为 0.19999999999999991。
在 decimalRemainder的表达式,文本类型字符 D 将两个操作数均强制转换为 Decimal,并且, 0.2 将具有精确的表示形式。 因此 Mod 运算符将得到的余数 0.0。
请注意声明 decimalRemainder 作为 Decimal是不够的。 您还必须将文本强制为 Decimal,也使用 Double 默认情况下,它的 decimalRemainder 采用不正确的值和 doubleRemainder相同。
boolean 类型不能准确地转换为数值类型
Boolean 数据类型 (Visual Basic) 值是存储为数字,因此,存储的值也不用等效于数字。 为了与早期版本兼容, Visual Basic 提供转换关键字 (CType 函数 (Visual Basic), CBool, CInt,等等) 将 Boolean 和 numeric 类型之间。 但是,其他语言有时会以不同的方式执行这些转换,如 .NET Framework 方法。
绝不应依赖于 True 和 False的等效数字值的代码。 只要有可能,应为它们设计的逻辑值限制 Boolean 变量用法。 如果必须组合 Boolean 和数值,请确保您了解您选择的转换方法。
在 Visual Basic 中的转换
当您使用 CType 或 CBool 转换关键字将数值数据类型转换为 Boolean时, 0 成为 False ,而所有其他值将成为 True。 通过使用转换关键字时,如果转换 Boolean 值转换为数值类型, False 变为 0,并 True 会变为 -1。
框架中的转换
Convert 类的 ToInt32 方法在 System 命名空间的转换 True 为 +1。
如果必须将 Boolean 值转换为数值数据类型,请注意所使用的转换方法。
字符文本产生编译器错误
如果没有任何类型字符时, Visual Basic 假定文本使用默认数据类型。 字符文本的默认类型 —将括在引号 (" ") —是 String。
String 数据类型不 Char 数据类型 (Visual Basic)会扩大到。 这意味着,如果要分配文本到 Char 变量,则必须进行收缩转换或将文本强制 Char 类型。
创建一个字符文本分配给变量或常数 |
|
下面的示例演示 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")
始终有使用收缩转换的一种风险,,因为它们可能会在运行时。 例如,因此,如果 String 值包含多个字符,从 String 的转换到 Char 会失败。 因此,它是使用 C 类型的更好的编程字符。
字符串转换在运行时失败
String 数据类型 (Visual Basic) 参与非常少的扩大转换。 String 只扩大到自身和 Object,因此,仅 Char 和 Char() ( Char 数组) 扩大到 String。 这是因为, String 变量和常数可以包含其他数据类型不能包含的值。
在类型检查开关 (Option Strict 语句) 为时 On,编译器不允许任何隐式收缩转换。 这包括涉及 String的功能。 您的代码仍可以使用转换关键字例如 CStr 和 CType 函数 (Visual Basic),处理 .NET Framework 尝试进行转换。
备注
收缩转换错误为从元素的转换禁止在 For Each…Next 收集到循环控制变量。有关更多信息和示例,请参见 “收缩转换” For Each...Next 语句 (Visual Basic)一节。
收缩转换保护
收缩转换的缺点是它们可能会在运行时。 例如,除 “true”或 “false " 以外,因此,如果 String 变量包含任何内容,则无法转换为 Boolean。 如果它包含标点符号,为任何数值类型的转换失败。 除非您知道您的 String 变量始终表示目标类型可以接受的值,则不应尝试进行转换。
如果必须从 String 转换为另一种数据类型,则最安全的做法是将尝试的转换 Try...Catch...Finally 语句 (Visual Basic)。 这使您能处理运行时失败。
字符数组
唯一 Char 和数组 Char 元素两个扩大到 String。 但是, String 不会扩大到 Char()。 若要将 String 值转换为 Char 数组,可以使用 System.String 类的 ToCharArray 方法。
无意义的值
通常, String 值并没有意义在其他数据类型,因此,转换是人工和高度危险的。 只要有可能,应为它们设计的字符序列限制 String 变量用法。 绝不应依赖其他类型的等效值编写代码。