2010-09-01 66 views
37

我正在使用一些VB.NET代碼,它似乎正在使用CInt(myBoolean)將布爾值轉換爲整數。發生的奇怪之處在於,如果值爲真,則返回-1。例如:將一個布爾值轉換爲一個整數返回值爲true?

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

這在其他語言中很普遍嗎?

我認爲布爾值如果爲真則爲1,如果爲假則爲0。此外,有沒有辦法讓Visual Basic分配1爲true而不是分配-1?

回答

35

通常,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

9

它看起來像一個陷阱,我不知道這種行爲的任何其他例子。

http://msdn.microsoft.com/en-us/library/ae382yt8.aspx指定了這種行爲,用「不要這樣做,mkay」對它進行評論。待辦事項進一步下跌:

轉換的框架

System命名空間Convert類的ToInt32方法將true轉換爲+1。

如果您必須將布爾值轉換爲數字數據類型,請注意您使用的轉換方法。

11

一個解決您最初的用途是:

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

這將返回一個0

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

這將返回一個1

4

MSDN documentation提供了一些寶貴的見解:

B oolean值不作爲數字存儲,並且存儲的值不打算等同於數字。你不應該編寫依賴於True和False等價數值的代碼。只要有可能,您應該將布爾變量的使用限制爲它們所設計的邏輯值。

4

我有同樣的問題和結果:)

4

在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()的行爲與隱式轉換行爲有所不同。

3

我測試,並得到以下結果:

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。但是這些都是轉換器,並沒有對二進制值做任何說明。

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 
1

之前,我希望是可以幫助別人裏面VB.NET布爾工作。 正如一個更好的方式來寫的Roger寫的VB.NET:

Public Function BoolToMySql(bVal As Boolean) As Integer 
    return If(bVal, 1, 0) 
End Function 
相關問題