vb.net 将布尔值转换为整数返回 -1 为真?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3621037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 15:01:30  来源:igfitidea点击:

Casting a boolean to an integer returns -1 for true?

vb.netboolean

提问by Barlow Tucker

I am working with some VB.NETcode that seems to be casting a boolean value to an integer using CInt(myBoolean). The odd thing that is happening is that it returns -1 if the value is true. For example:

我正在使用一些VB.NET代码,这些代码似乎使用CInt(myBoolean). 发生的奇怪事情是,如果值为真,它返回 -1。例如:

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

Is this common in other languages?

这在其他语言中是否常见?

I thought that a boolean would be 1 if true and 0 if false. Also, is there a way to make Visual Basic assign 1 to true instead of assigning -1?

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

采纳答案by Thomas Owens

Typically, a value of false is represented by 0 and a value of true is represented by any non-0 integer value. The specific value for true and false (among others) are things that you shouldn't rely on - they can potentially be implementation specific. I'm not sure what you are trying to do, but it would probably be best to not rely on Trueor Falsehaving any specific integer values unless you absolutely have to.

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

The best explanation that I could find for VB's specific behavior comes from Wikipedia:

我能找到的关于 VB 特定行为的最佳解释来自维基百科

Boolean constant True has numeric value ?1. This is because the Boolean data type is stored as a 16-bit signed integer. In this construct ?1 evaluates to 16 binary 1s (the Boolean value True), and 0 as 16 0s (the Boolean value False). This is apparent when performing a Not operation on a 16 bit signed integer value 0 which will return the integer value ?1, in other words True = Not False. This inherent functionality becomes especially useful when performing logical operations on the individual bits of an integer such as And, Or, Xor and Not.[4] This definition of True is also consistent with BASIC since the early 1970s Microsoft BASIC implementation and is also related to the characteristics of CPU instructions at the time.

布尔常量 True 的数值为?1。这是因为布尔数据类型存储为 16 位有符号整数。在此构造中,?1 计算为 16 个二进制 1(布尔值 True),而 0 计算为 16 个 0(布尔值 False)。这在对 16 位有符号整数值 0 执行 Not 操作时很明显,该值将返回整数值 ?1,换句话说,True = Not False。在对整数的各个位(例如 And、Or、Xor 和 Not)执行逻辑运算时,这种固有功能变得特别有用。 [4] 这种True的定义也与1970年代早期微软BASIC实现以来的BASIC一致,也与当时CPU指令的特性有关。

回答by Michael Eakins

A work around for your initial use would be :

您最初使用的解决方法是:

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

This will return a 0.

这将返回 0。

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

This will return a 1.

这将返回 1。

回答by Martijn

It seems like a gotcha, and I don't know any other examples of this behaviour.

这似乎是一个陷阱,我不知道这种行为的任何其他例子。

http://msdn.microsoft.com/en-us/library/ae382yt8.aspxspecifies this behaviour, with a "Don't do that, mkay" sorta remark with it. Do note further down:

http://msdn.microsoft.com/en-us/library/ae382yt8.aspx指定了这种行为,并带有“不要这样做,mkay”之类的评论。请进一步注意:

Conversion in the Framework

框架中的转换

The ToInt32 method of the Convert class in the System namespace converts True to +1.

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

If you must convert a Boolean value to a numeric data type, be careful about which conversion method you use.

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

回答by dbasnett

The MSDN documentationprovides some valuable insight:

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

Boolean values are not stored as numbers, and the stored values are not intended to be equivalent to numbers. You should never write code that relies on equivalent numeric values for True and False. Whenever possible, you should restrict usage of Boolean variables to the logical values for which they are designed.

布尔值不存储为数字,并且存储的值不打算等同于数字。您永远不应该编写依赖于 True 和 False 的等效数值的代码。只要有可能,您应该将布尔变量的使用限制为为其设计的逻辑值。

回答by marco

I had the same problem and used Math.Absfunction on the result :)

我遇到了同样的问题并Math.Abs在结果上使用了函数:)

回答by supercat

Many versions of BASIC in the 1970's and 1980's implemented bit-wise arithmetic with their ANDand ORoperators, and made true conditional expressions evaluate to -1 (i.e. the "all-bits-set" value in the two's complement used for integers). I'm not sure exactly why the decision was made to have true conditional expressions evaluate to an all-bits-set value; being able to use ANDto mask an integer against a conditional expression may have been faster than multiplying, but given then internal mechanics of the interpreters the difference would have been slight.

1970 年代和 1980 年代的许多 BASIC 版本都使用它们的ANDandOR运算符实现了按位算术,并使真条件表达式的计算结果为 -1(即用于整数的二进制补码中的“all-bits-set”值)。我不确定为什么决定让真正的条件表达式评估为所有位设置的值;能够使用AND条件表达式屏蔽整数可能比乘法更快,但考虑到解释器的内部机制,差异会很小。

In any case, the first versions of BASIC that Microsoft produced for the PC followed in that tradition of having true conditionals evaluate to -1 (all-bits-set); since QuickBASIC was in turn supposed to be compatible with those, and Visual Basic was supposed to be compatible with QuickBASIC, they used the same representation. Although .Net recognizes integers and Booleans as different types, VB.Net wanted to offer a migration path for VB6 programs that might rely on the old behavior. With "Option Strict Off", VB.Net will implicitly convert a Boolean value of True to an integer -1; while most programmers use Option Strict On, it would be confusing to have the behavior of CInt()differ from the implicit conversion behavior.

无论如何,微软为 PC 生产的 BASIC 的第一个版本遵循了真正条件评估为 -1(所有位集)的传统;由于 QuickBASIC 反过来应该与这些兼容,并且 Visual Basic 应该与 QuickBASIC 兼容,因此它们使用相同的表示形式。尽管 .Net 将整数和布尔值识别为不同类型,但 VB.Net 希望为可能依赖旧行为的 VB6 程序提供迁移路径。使用“Option Strict Off”,VB.Net 会隐式将布尔值 True 转换为整数 -1;虽然大多数程序员使用Option Strict On,但如果 的行为CInt()与隐式转换行为不同,则会令人困惑。

回答by Martin Mulder

I tested it and got the following results:

我测试了它并得到以下结果:

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

This will result in:

这将导致:

1
1

1
1

I hope this proves that all Truevalues inside .NET are always the same. The reason is simple: All .NET members have to communicatie with each other. It would be weird if object.Equals(trueFromCSharp, trueFromVB)would result in false (as will trueFromCSharp == trueFromVB).

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

CIntis just a function which will convert Trueinto -1. Another function Intwill return 1. But these are converters, and do not say anything about the binary values.

CInt只是一个将转换True-1. 另一个函数Int将返回1. 但这些是转换器,并没有说明二进制值。

回答by Roger

I have been having the same problem with MySQL as this has no Boolean type only a tinyint(1).

我在 MySQL 上遇到了同样的问题,因为它没有布尔类型,只有一个 tinyint(1)。

My solution was to write a converter function to ensure that the values are correct before inserting them into the database

我的解决方案是编写一个转换器函数以确保在将它们插入数据库之前这些值是正确的

        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

回答by John Grabauskas

I hope that is can help others work with Booleans inside VB.NET. Just as a better way to write the VB.NET that Roger wrote:

我希望这可以帮助其他人在 VB.NET 中使用布尔值。就像编写 Roger 写的 VB.NET 的更好方法一样:

Public Function BoolToMySql(bVal As Boolean) As Integer
   return  If(bVal, 1, 0)
End Function