我正在使用一些VB.NET代碼,它似乎正在使用CInt(myBoolean)
將布爾值轉換爲整數。發生的奇怪之處在於,如果值爲真,則返回-1。例如:將一個布爾值轉換爲一個整數返回值爲true?
CInt(True) // returns -1
CInt(False) // returns 0
這在其他語言中很普遍嗎?
我認爲布爾值如果爲真則爲1,如果爲假則爲0。此外,有沒有辦法讓Visual Basic分配1爲true而不是分配-1?
我正在使用一些VB.NET代碼,它似乎正在使用CInt(myBoolean)
將布爾值轉換爲整數。發生的奇怪之處在於,如果值爲真,則返回-1。例如:將一個布爾值轉換爲一個整數返回值爲true?
CInt(True) // returns -1
CInt(False) // returns 0
這在其他語言中很普遍嗎?
我認爲布爾值如果爲真則爲1,如果爲假則爲0。此外,有沒有辦法讓Visual Basic分配1爲true而不是分配-1?
通常,false值由0表示,true值由任何非0整數值表示。 true和false(以及其他)的具體價值是你不應該依賴的東西 - 它們可能是特定於實現的。我不確定你想要做什麼,但最好不要依賴True
或False
具有任何特定的整數值,除非你絕對必須這樣做。
,我能找到的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指令的特徵相關。
它看起來像一個陷阱,我不知道這種行爲的任何其他例子。
http://msdn.microsoft.com/en-us/library/ae382yt8.aspx指定了這種行爲,用「不要這樣做,mkay」對它進行評論。待辦事項進一步下跌:
轉換的框架
System命名空間Convert類的ToInt32方法將true轉換爲+1。
如果您必須將布爾值轉換爲數字數據類型,請注意您使用的轉換方法。
一個解決您最初的用途是:
Dim i As Integer = CInt(Int(False))
這將返回一個0
Dim i As Integer = CInt(Int(True))
這將返回一個1
的MSDN documentation提供了一些寶貴的見解:
B oolean值不作爲數字存儲,並且存儲的值不打算等同於數字。你不應該編寫依賴於True和False等價數值的代碼。只要有可能,您應該將布爾變量的使用限制爲它們所設計的邏輯值。
我有同樣的問題和結果:)
在1970年的許多版本的BASIC和1980年與他們AND
和OR
運營商實現逐位運算,並取得真正的條件表達式中使用Math.Abs
功能評估爲-1(這是「全比特集」值)。我不確定爲什麼做出這樣的決定:將真實條件表達式評估爲全比特集值;能夠使用AND
根據條件表達式來屏蔽整數可能比乘法更快,但是如果給出解釋器的內部機制,則差異將會很小。在任何情況下,微軟爲個人電腦生產的BASIC的第一個版本都遵循傳統的條件爲-1(全部位)的傳統;因爲QuickBASIC反過來被認爲與這些兼容,並且Visual Basic應該與QuickBASIC兼容,他們使用相同的表示。儘管.Net將整數和布爾值識別爲不同的類型,但vb.net想爲VB6程序提供可能依賴於舊行爲的遷移路徑。通過「選項嚴格關閉」,VB.Net將隱含地將布爾值True轉換爲整數-1;雖然大多數程序員使用Option Strict On
,但令人困惑的是,CInt()
的行爲與隱式轉換行爲有所不同。
我測試,並得到以下結果:
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
。但是這些都是轉換器,並沒有對二進制值做任何說明。
我一直有與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
之前,我希望是可以幫助別人裏面VB.NET布爾工作。 正如一個更好的方式來寫的Roger寫的VB.NET:
Public Function BoolToMySql(bVal As Boolean) As Integer
return If(bVal, 1, 0)
End Function
我剛測試這個premis。 VB.NET中的布爾值不等於'-1',它等於'1'。我通過使用FieldOffsetAttribute製作一個具有兩個重疊字段的結構來檢查此問題。這樣你可以看到一個布爾值的確切二進制值。'CInt'只是一個轉換。參考舊文檔並不能真正幫助我猜。 – 2013-05-09 15:07:36
我在''True'中傳入了一個接受整數的函數,並在VB.NET中獲得了值'-1'。在文章Martjin引用(http://msdn.microsoft.com/en-us/library/ae382yt8.aspx)中,似乎如何轉換布爾值將決定您獲得的整數值。 – 2013-10-18 15:05:45