2013-01-22 80 views
10

我想知道为什么真等于-1,而不是1。如果我没有记错的C(在天回),“真”是等于1为什么是真等于-1

Dim t, f As Integer 

    t = True 
    f = False 

    Console.WriteLine(t) ' -1 
    Console.WriteLine(f) ' 0 
    Console.ReadLine() 
+4

True将所有位设置为1.对于所有有符号的整数类型,恰好等于-1。 –

+0

在C中,false等于0.任何其他值都为true,包括-1。请注意,-1等于'不是0'使用二进制'不' –

+0

试试可能。 – Guy

回答

17

当您将任何非零数字转换为Boolean时,它将评估为True。例如:

Dim value As Boolean = CBool(-1) ' True 
Dim value1 As Boolean = CBool(1) ' True 
Dim value2 As Boolean = CBool(0) ' False 

然而,正如你所指出的,任何时候你施放被设置为TrueInteger一个Boolean,它会评估为-1,例如:

Dim value As Integer = CInt(CBool(1)) ' -1 

的原因是因为-1是其所有位等于1的带符号整数值。由于Boolean存储为16位整数,因此只需NOT'ing all即可更容易地在真状态和假状态之间切换的位而不是仅仅不是最低位的位。换句话说,为了True1,那就必须存储这样的:

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 

如果你使用无符号整数这将是比较明显的,因为那时的True的值是最大的价值,而不是-1。例如:

Dim value As UInt16 = CType(True, UInt16) ' 65535 

因此,真正的问题是为什么VB.NET使用16位来存储单个位的值。真正的原因是速度。是的,它使用了16倍的内存量,但是处理器可以比单比特布尔操作快得多的16位布尔操作。

为什么-1存储为1111111111111111而不是1000000000000001,正如你所预料的原因(第一位为符号位,其余为正常价值),是因为它被存储为二进制补码。作为二进制补码存储负数意味着处理器执行算术运算要容易得多。

+1

很好的答案!我从来没有考虑过'NOT(1)<> 0'会成为问题。 –

2

是大多数语言,数值为0是错误的。一切都被认为是真实的。如果我记得正确,-1实际上是所有位都设置为1,而0是所有位设置为0.我想这就是原因。

+0

是的,你会看到很多“真正的”字样“非零” – hometoast

0

下面是可能重复:Casting a boolean to an integer returns -1 for true?

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

0

在Visual Basic,0False而任何非零值是True。此外,每MSDN

当Visual Basic数字数据类型值转换为Boolean,0 变得虚假和所有其他值成为现实。当Visual Basic 将布尔值转换为数字类型时,False变为0,而真 变为-1。

0

我想回到汇编语言,其中条件转换为比较cmp操作并检查零标志(ZF)。对于真正的表达式,ZF不会引发,并且对于错误表达式而言。早期的英特尔处理器就是这样,但我不记得Zilog Z80和摩托罗拉8位处理器是否具有相同的约定。