将一个布尔值转换为一个整数返回值为true?

问题描述:

我正在使用一些VB.NET代码,它似乎正在使用CInt(myBoolean)将布尔值转换为整数。发生的奇怪之处在于,如果值为真,则返回-1。例如:将一个布尔值转换为一个整数返回值为true?

CInt(True) // returns -1 
CInt(False) // returns 0 

这在其他语言中很普遍吗?

我认为布尔值如果为真则为1,如果为假则为0。此外,有没有办法让Visual Basic分配1为true而不是分配-1?

通常,false值由0表示,true值由任何非0整数值表示。 true和false(以及其他)的具体价值是你不应该依赖的东西 - 它们可能是特定于实现的。我不确定你想要做什么,但最好不要依赖TrueFalse具有任何特定的整数值,除非你绝对必须这样做。

,我能找到的VB的具体行为的最好解释来自Wikipedia

布尔常量真正具有数字值-1。这是因为布尔数据类型存储为16位有符号整数。在这个结构中,-1计算为16个二进制1(布尔值为True),0为16 0(布尔值为False)。在对16位有符号整数值0执行“否”操作时这很明显,该值将返回整数值-1,换句话说,True = Not False。当对诸如And,Or,Xor和Not等整数的各个位执行逻辑运算时,这种固有的功能变得特别有用[4]。 True的这个定义也与70年代早期的BASIC实现一致,并且与当时的CPU指令的特征相关。

+2

我刚测试这个premis。 VB.NET中的布尔值不等于'-1',它等于'1'。我通过使用FieldOffsetAttribute制作一个具有两个重叠字段的结构来检查此问题。这样你可以看到一个布尔值的确切二进制值。'CInt'只是一个转换。参考旧文档并不能真正帮助我猜。 – 2013-05-09 15:07:36

+1

我在''True'中传入了一个接受整数的函数,并在VB.NET中获得了值'-1'。在文章Martjin引用(http://msdn.microsoft.com/en-us/library/ae382yt8.aspx)中,似乎如何转换布尔值将决定您获得的整数值。 – 2013-10-18 15:05:45

它看起来像一个陷阱,我不知道这种行为的任何其他例子。

http://msdn.microsoft.com/en-us/library/ae382yt8.aspx指定了这种行为,用“不要这样做,mkay”对它进行评论。待办事项进一步下跌:

转换的框架

System命名空间Convert类的ToInt32方法将true转换为+1。

如果您必须将布尔值转换为数字数据类型,请注意您使用的转换方法。

一个解决您最初的用途是:

Dim i As Integer = CInt(Int(False)) 

这将返回一个0

Dim i As Integer = CInt(Int(True)) 

这将返回一个1

MSDN documentation提供了一些宝贵的见解:

B oolean值不作为数字存储,并且存储的值不打算等同于数字。你不应该编写依赖于True和False等价数值的代码。只要有可能,您应该将布尔变量的使用限制为它们所设计的逻辑值。

我有同样的问题和结果:)

在1970年的许多版本的BASIC和1980年与他们ANDOR运营商实现逐位运算,并取得真正的条件表达式中使用Math.Abs功能评估为-1(这是“全比特集”值)。我不确定为什么做出这样的决定:将真实条件表达式评估为全比特集值;能够使用AND根据条件表达式来屏蔽整数可能比乘法更快,但是如果给出解释器的内部机制,则差异将会很小。在任何情况下,微软为个人电脑生产的BASIC的第一个版本都遵循传统的条件为-1(全部位)的传统;因为QuickBASIC反过来被认为与这些兼容,并且Visual Basic应该与QuickBASIC兼容,他们使用相同的表示。尽管.Net将整数和布尔值识别为不同的类型,但vb.net想为VB6程序提供可能依赖于旧行为的迁移路径。通过“选项严格关闭”,VB.Net将隐含地将布尔值True转换为整数-1;虽然大多数程序员使用Option Strict On,但令人困惑的是,CInt()的行为与隐式转换行为有所不同。

我测试,并得到以下结果:

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); 
} 

这将导致:

我希望这证明.NET中的所有True值始终是相同的。原因很简单:所有.NET成员都必须相互沟通。如果object.Equals(trueFromCSharp, trueFromVB)会导致错误(如trueFromCSharp == trueFromVB),那将很奇怪。

CInt只是将True转换为-1的函数。另一个功能Int将返回1。但是这些都是转换器,并没有对二进制值做任何说明。

我一直有与MySQL相同的问题,因为这没有布尔类型只有tinyint(1)。

我的解决办法是写一个转换器功能,以确保值是正确的将它们插入到数据库

 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