2009-04-13 3 views
29

の整数にブールに変換:これは次のように出力さ次のコードくださいVB.NET

Sub Main() 

    Dim i As Integer 
    Dim b As Boolean 

    i = 1 
    b = i 
    i = b 
    Console.WriteLine(i) 

    i = Convert.ToInt32(b) 
    Console.WriteLine(i) 

End Sub 

を:

-1 
1 

これはなぜですか?

として

(ジャストジョーク:)あなたは0があまりにも...

Int32.TryParse("True", i) 
Console.WriteLine(i) 

答えて

43

は、その頭を示すレガシーコードのビットです。

問題の中心は、VT_BOOLタイプです。 Visual Basic 6.0では、ブール値としてVT_BOOL型(AKA VARIANT_BOOL)が使用されていました。 VARIANT_BOOLの場合、Trueは整数値-1を持つVARIANT_TRUE値で表されます。 .NETへの変換中に、Visual Basicの変換ルーチンを使用してブール値をInteger値に変換すると、Visual Basic 6.0のセマンティクスは戻り値に維持されることになりました。 -1になります。

最初の暗黙的な変換は、b = i行で行われます。フードの下では、これは整数から論理値への暗黙の変換を行います。 0以外の値はtrueとみなされるため、結果の値はtrueです。

ただし、次のコード行は暗黙的に整数型に変換しています。これは整数に値を変換するために、Visual Basicの変換ルーチン(CType又はCInt)のいずれかを使用してフードの下

。そのようなVisual Basicのセマンティクスが有効なので、返される値は-1です。

次の興味深い行は、Convert.ToInt32()行です。これは、Visual Basicのセマンティクスを使用しない.NET変換ルーチンを使用しています。代わりに、基礎となるBCLの表現に真のブール値1を返します。

+4

WHY VT_BOOLが使用された理由と値が-1である理由について、いくつか追加したいことがあります。 VB 6には、論理演算とビット演算の両方を行う "and"演算子と "or"演算子が1セットしかありませんでした(ほとんどの言語は2セットあります)。 これは "and"を "&"として実装し、リテラルのデフォルトを-1にすることで機能しました。 –

+0

"真とx"は "x"がゼロでないときはいつでも非ゼロです。 –

+0

ここでは、ほとんど関係のない質問に対する私の答えで「なぜ」の感覚を得ることができます:https://stackoverflow.com/a/46331671/3043 –

25

いくつかの言語があることがブール真-1ではなく、1より考える得ることができ、私は理由を確認するために研究を行う必要があるだろう、私は思い出しません。

VB6では、定数Trueの値は-1です。

ただし、Convert.ToInt32(Boolean)documentedです。「値がtrueの場合は1、それ以外の場合は0」を返します。そうすれば、どのフレームワーク言語を使用していても同じです。

編集:VB.NETに、ブール値であるため-1真と偽のために0にデフォルトでの質問boolean true -- positive 1 or negative 1

+0

一部の言語は '使用-1'、は' true'として、それが使用するようなので、すべてのビットがゼロのバイナリ表現の反対で、 '0b11111111'であるため、一方のビット単位のNOT演算は他方の演算結果になります。 – mbomb007

1

を参照してください。私は、MSDNのVisual Basicドキュメントから

7

...それはしかし、1のような第2の時間を印刷し、なぜわからない:

Visual Basicはブールに数値 データ型の値を変換しType Conversions、 0は となり、その他の値はすべて となります。 Visual Basicが ブール値を数値型に変換する場合、False は0になり、Trueは-1になります。

そしてConvert.ToInt32(value)用:値がtrueの場合

は、数1をretuns。それ以外の場合は 、あなたのコードのためのだから、0

:あなたが見ている何

i = 1 
b = i // b becomes true 
i = b // true = -1 
Console.WriteLine(i) // i is -1 

i = Convert.ToInt32(b) // Convert.ToInt32(true) = 1 
Console.WriteLine(i) // i is 1 
+0

これらの文書引用のリンクを追加すると、私はアップモードになります。 –

10

なぜ-1がTrueに使用されているかについては、それは文字通り(0ではない)ためだと思います。

ゼロから始まり、すべてのビットを反転して2の補数として読んでください。負の値が出てきます。

FalseでないものはTrue、Falseは0なので、(NOT False)は-1で表されます。

これはちょうど偶然かもしれません....

+3

これは、VBがTrueの場合に-1を使用する理由です。 :) –

+1

+1。興味深いことに、 "true"が-1の場合、ブール論理と整数ビットマスキングに同じ演算子を使用できます。 "and"と "or"を短絡するかどうかの問題は、 '真の'オペランドを強制的に単一の値にする必要があるかどうかという問題とは無関係であることに注意することも興味深い。 – supercat

1

すべての数値データ型はブール値として使用できます。結果は、使用されるデータ型に依存します。

例:

Dim i As Byte ' Byte is non-signed! 
Dim b As Boolean = True 

i = b   ' Set first (lowest) bit of i (non-signed byte) 
' i is now binary 0000 0001 = 1! 


Dim i As SByte ' SByte is signed! 
Dim b As Boolean = True 

i = b   ' Set all bits of i (signed byte) 
' i is now FF (binary 1111 1111 = -1 ! 

整数が署名され、整数に真 - > -1。

UIntegerがuintに真、非署名されている - > 1.

のように...

偽の値が符号付き数値で最上位ビットをクリアし、非署名数字で最も低いです。

したがって、すべての数値データ型でFalseが0になります。

2

"True"は数値データ型の0値からの否定です!

はない(0)以外の署名タイプのない(0)署名されたタイプの

1.返し-1。

コードがわからない場合は、コードが2回目に内部データ変換を実行する可能性があります。

1

これは危険な答えですが、:

Dim b As Boolean 
    b = False 
    Dim i As Integer 
    i = IIf(b, 1, 0) 
関連する問題