将一个布尔值转换为一个整数返回-1为真?
我正在使用一些VB.NET代码,似乎是使用CInt(myBoolean)
将一个布尔值转换为一个整数。 奇怪的是,如果值为真,则返回-1。 例如:
CInt(True) // returns -1 CInt(False) // returns 0
这在其他语言中很常见吗?
我认为布尔值如果为true,则为1,如果为false,则为0。 此外,有没有办法让Visual Basic分配1为true而不是分配-1?
通常,false值由0表示,true值由任何非0整数值表示。 真假的具体价值(除其他外)是你不应该依赖的东西 – 它们可能是实现特定的。 我不确定你在做什么,但是最好不要依赖True
或False
,除非你绝对需要。
我可以findVB的具体行为的最好的解释来自维基百科 :
布尔常量True具有数值-1。 这是因为布尔数据types存储为一个16位有符号整数。 在这个结构中,-1计算为16个二进制1(布尔值True),0计为16 0(布尔值False)。 在16位有符号整数值0上执行一个非操作,这将返回整数值-1,换句话说,True = Not False,这是显而易见的。 当对诸如And,Or,Xor和Not等整数的各个位执行逻辑运算时,这种固有的function变得特别有用。 True的这个定义也符合BASIC自20世纪70年代初以来的Microsoft BASIC的实现,也与当时CPU指令的特点有关。
初次使用的解决方法是:
Dim i As Integer = CInt(Int(False))
这将返回一个0。
Dim i As Integer = CInt(Int(True))
这将返回1。
这似乎是一个陷阱,我不知道这种行为的任何其他例子。
http://msdn.microsoft.com/en-us/library/ae382yt8.aspx指定了这种行为,用“不要这样做,mkay”来评论它。; 请注意:
框架中的转换
System命名空间中的Convert类的ToInt32方法将True转换为+1。
如果您必须将布尔值转换为数字数据types,请注意您使用的转换方法。
我有同样的问题,并使用Math.Abs
函数的结果:)
BASIC在1970年代和1980年代的许多版本都用它们的AND
和OR
运算符实现了比特算术运算,并将真正的条件expression式评估为-1(这是“全比特集”值)。 我不确定为什么决定真正的条件expression式评估为全位数值; 能够使用AND
来掩饰一个整数与条件expression式的比较可能比乘法更快,但是如果给出解释器的内部机制,那么差异就会很小。
在任何情况下,微软为个人电脑制作的BASIC的第一个版本都遵循传统的条件为-1(全部位)的传统; 因为QuickBASIC反过来被认为与这些兼容,并且Visual Basic应该与QuickBASIC兼容,他们使用相同的表示法。 尽pipe.Net将整数和布尔值识别为不同的types,但是vb.net希望为VB6程序提供一个可能依赖于旧行为的迁移path。 使用“Option Strict Off”,VB.Net会隐式地将一个布尔值True转换为一个整数-1; 而大多数程序员使用Option Strict On
, CInt()
的行为与隐式转换行为有所不同。
MSDN文档提供了一些有价值的见解:
布尔值不作为数字存储,并且存储的值不打算等同于数字。 你不应该编写依赖于True和False等价数值的代码。 只要有可能,就应该将布尔variables的使用限制在它们所devise的逻辑值上。
我testing了一下,结果如下:
Public Module BooleanTest Public Function GetTrue() As Boolean GetTrue = True End Function End Module
…
[StructLayout(LayoutKind.Explicit)] struct MyStruct { [FieldOffset(0)] public bool MyBool; [FieldOffset(0)] public int MyInt32; } static void Main(string[] args) { MyStruct b1, b2; b1.MyInt32 = 0; b2.MyInt32 = 0; b1.MyBool = BooleanTest.BooleanTest.GetTrue(); b2.MyBool = true; Console.WriteLine(b1.MyInt32); Console.WriteLine(b2.MyInt32); }
这将导致:
1
1
我希望这certificate.NET中的所有True
值总是相同的。 原因很简单:所有.NET成员都必须相互沟通。 如果object.Equals(trueFromCSharp, trueFromVB)
会导致false(如trueFromCSharp == trueFromVB
) object.Equals(trueFromCSharp, trueFromVB)
那将会很奇怪。
CInt
只是一个将True
转换为-1
的函数。 另一个函数Int
将返回1
。 但是这些都是转换器,并不会说二进制值。
我一直有与MySQL相同的问题,因为这没有布尔types只tinyint(1)。
我的解决scheme是编写一个转换器函数,以确保在将值插入数据库之前,这些值是正确的
Public Function BoolToMySql(bVal As Boolean) As Integer Dim retVal As Integer If bVal = True Then retVal = 1 Else retVal = 0 End If BoolToMySql = retVal End Function
我希望可以帮助其他人在VB.NET中使用布尔值。 就像Roger写的VB.NET的一个更好的方法:
Public Function BoolToMySql(bVal As Boolean) As Integer return If(bVal, 1, 0) End Function