Trueが1ではなく-1に等しいのはなぜだろうと思っていました。Cで正しく覚えていれば(昔は)、「true」は1に等しいでしょう。
Dim t, f As Integer
t = True
f = False
Console.WriteLine(t) ' -1
Console.WriteLine(f) ' 0
Console.ReadLine()
Trueが1ではなく-1に等しいのはなぜだろうと思っていました。Cで正しく覚えていれば(昔は)、「true」は1に等しいでしょう。
Dim t, f As Integer
t = True
f = False
Console.WriteLine(t) ' -1
Console.WriteLine(f) ' 0
Console.ReadLine()
ゼロ以外の数値をにキャストするとBoolean
、に評価されTrue
ます。例えば:
Dim value As Boolean = CBool(-1) ' True
Dim value1 As Boolean = CBool(1) ' True
Dim value2 As Boolean = CBool(0) ' False
ただし、ご指摘のとおり、にBoolean
設定されているTrue
をキャストするとInteger
、次のように-1と評価されます。
Dim value As Integer = CInt(CBool(1)) ' -1
これは-1
、すべてのビットが1に等しい符号付き整数値であるためBoolean
です。aは16ビット整数として格納されるため、すべてを単純にしないことで、真と偽の状態を簡単に切り替えることができます。最下位のビットだけではなく、ビット。つまり、であるためには、次のTrue
よう1
に格納する必要があります。
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が1ビット値を格納するために16ビットを使用するのかということです。本当の理由はスピードです。はい、16倍のメモリを使用しますが、プロセッサは、シングルビットのブール演算よりもはるかに高速に16ビットのブール演算を実行できます。
補足:予想どおり、のInt16
値がasではなくasとして-1
格納される理由(最初のビットは「符号ビット」で、残りは値)は、2の補数として格納されるためです。 -補体。2の補数として負の数を格納することは、プロセッサが算術演算を実行するのがはるかに簡単であることを意味します。また、2つの補数では、負の数として表す方法がないため、より安全です。これにより、あらゆる種類の混乱やバグが発生する可能性があります。1111111111111111
1000000000000001
0
ほとんどの言語であり、0の数値はfalseです。他のすべては真実と見なされます。正しく覚えていれば、-1は実際にはすべてのビットが1に設定され、0はすべてのビットが0に設定されています。これが理由だと思います。
Visual Basicでは、0
はですがFalse
、ゼロ以外の値はTrue
です。また、MSDNによると:
Visual Basicが数値データ型の値をブール値に変換すると、0はFalseになり、他のすべての値はTrueになります。Visual Basicがブール値を数値型に変換すると、Falseは0になり、Trueは-1になります。
重複の可能性は次のとおりです。ブール値を整数にキャストすると、trueの場合は-1が返されますか?
ブール定数Trueの数値は-1です。これは、ブールデータ型が16ビットの符号付き整数として格納されているためです。この構成では、-1は16個のバイナリ1(ブール値True)に評価され、0は16個の0(ブール値False)に評価されます。これは、整数値-1を返す16ビット符号付き整数値0に対してNot演算を実行する場合、つまりTrue =NotFalseの場合に明らかです。この固有の機能は、And、Or、Xor、Notなどの整数の個々のビットに対して論理演算を実行するときに特に役立ちます。[4] このTrueの定義は、1970年代初頭のMicrosoft BASIC実装以降のBASICとも一致しており、当時のCPU命令の特性にも関連しています。
cmp
条件が比較操作に変換され、ゼロフラグ(ZF
)がチェックされるアセンブリ言語に戻ると思います。真の式の場合ZF
は発生しませんが、偽の式の場合は発生します。Z80
初期のIntelプロセッサはそのようなものですが、ZilogとMotorolaの8ビットプロセッサが同じ規則を持っていたかどうかは思い出せません。