我想知道为什么True等于-1而不是1.如果我在C中正确记得(在日子里),“true”将等于1.
Dim t, f As Integer
t = True
f = False
Console.WriteLine(t) ' -1
Console.WriteLine(f) ' 0
Console.ReadLine()
答案 0 :(得分:23)
当您将任何非零数字投射到Boolean
时,它将评估为True
。例如:
Dim value As Boolean = CBool(-1) ' True
Dim value1 As Boolean = CBool(1) ' True
Dim value2 As Boolean = CBool(0) ' False
但是,正如您所指出的那样,只要您将设置为Boolean
的{{1}}投射到True
,它就会评估为-1,例如:
Integer
原因是因为Dim value As Integer = CInt(CBool(1)) ' -1
是有符号整数值,其所有位都等于1.由于-1
存储为16位整数,因此更容易通过简单地不是所有的比特来切换真和假状态,而不是仅仅忽略比特的最低有效位。换句话说,为了Boolean
为True
,它必须像这样存储:
1
但是这样存储更容易:
True = 0000000000000001
False = 0000000000000000
更容易的原因是因为,在低级别:
True = 1111111111111111
False = 0000000000000000
鉴于:
1111111111111111 = NOT(0000000000000000)
例如,您可以使用0000000000000001 <> NOT(0000000000000000)
0000000000000001 = NOT(1111111111111110)
变量复制此行为,如下所示:
Int16
如果使用无符号整数,这将更加明显,因为Dim value As Int16 = 0
Dim value2 As Int16 = Not value
Console.WriteLine(value2) ' -1
的值是最大值而不是-1。例如:
True
因此,真正的问题是,为什么VB.NET使用16位来存储单个位值。真正的原因是速度。是的,它使用了16倍的内存量,但处理器可以比单位布尔运算快得多地执行16位布尔运算。
附注:Dim value As UInt16 = CType(True, UInt16) ' 65535
的{{1}}值存储为Int16
而不是-1
的原因,正如您所预期的那样(第一位将是“符号位”,其余的将是值),是因为它存储为二进制补码。将负数存储为二进制补码意味着算术运算对于处理器来说更容易执行。它也更安全,因为有了两个赞美,没有办法将1111111111111111
表示为负数,这可能会导致各种混乱和错误。
答案 1 :(得分:2)
是大多数语言,数字值为0是假的。其他一切都被认为是真实的。如果我记得正确,-1实际上所有位都设置为1而0是所有位设置为0.我想这就是原因。
答案 2 :(得分:0)
以下是可能的副本:Casting a boolean to an integer returns -1 for true?
布尔常量True的数值为-1。这是因为布尔数据类型存储为16位有符号整数。在此构造中,-1计算为16个二进制1(布尔值为True),0为16 0(布尔值为False)。当对16位有符号整数值0执行Not运算时,这将显而易见,该值将返回整数值-1,换句话说,True = Not False。当对整数的各个位执行逻辑运算时,这种固有功能变得特别有用,例如And,Or,Xor和Not。[4]自20世纪70年代早期的Microsoft BASIC实现以来,True的定义也与BASIC一致,并且还与当时CPU指令的特性有关。
答案 3 :(得分:0)
在Visual Basic中,0
为False
,而任何非零值均为True
。另外,按MSDN:
当Visual Basic将数值数据类型值转换为布尔值时,为0 变为False,所有其他值变为True。当Visual Basic时 将布尔值转换为数字类型,False变为0和True 变成-1。
答案 4 :(得分:0)
我想回到汇编语言,其中条件被转换为比较cmp
操作并且检查零标志(ZF
)。对于真正的表达式,不会引发ZF
,而对于伪表达式则不会引发Z80
。早期的英特尔处理器就是这样,但我不记得Zilog {{1}}和摩托罗拉8位处理器是否具有相同的约定。