2013-01-22 139 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位處理器是否具有相同的約定。