〜Trueが-2になるのはなぜですか?


132

Pythonコンソール:

~True

くれます:

-2

どうして?誰かがこの特定のケースをバイナリで私に説明できますか?


22
理由は~1されて-2:、試してみてくださいTrue == 1
Grijesh Chauhan

15
正確には、 " True is 1" は真実ではありませんが、は真実ですTrue == 1
バッハ

3
UNARY_INVERT(バイトコード全体)を見ると答えに何かが追加されると本当に思いますか?
Wooble 2014

2
この質問は重複ではありません!の特定の動作について尋ねboolます。それがどのように~機能するかについてではありません。実際、この質問への有効な答えは、2の補数について言及することを避け~、整数をどのように操作するかをまったく避けることができます。
Bakuriu 14

回答:


240

int(True)です1

1 です:

00000001

そして~1

11111110

どれ-22の補数1

1すべてのビットを反転し、結果の数値に1を加算し、結果を絶対値のバイナリ表現として解釈し、負の符号を追加します(数値は1で始まるため)。

11111110  00000001  00000010 
                    
       Flip       Add 1

これは2ですが、MSBが1であるため、符号は負です。


言及する価値がある:

考えてみてboolください。これは実際には数値であることがわかります-これには2つの値とがTrueありFalse、それらは整数1と0の「カスタマイズされた」バージョンであり、異なる方法でのみ表示されます。これらは整数型のサブクラスですint

したがって、それらは1と0とまったく同じように動作しますが、bool再定義しstrrepr異なる方法で表示する点が異なります。

>>> type(True)
<class 'bool'>
>>> isinstance(True, int)
True

>>> True == 1
True
>>> True is 1  # they're still different objects
False

1
ただ、@ofcapl言いたかった:がint('1')もある1が、~'1'一方、TypeError例外も~Trueあるため、これはされていないboolのサブクラスでintマルタインは彼の答えにこの情報を追加しました@が。
Grijesh Chauhan 14

レコード@ofcaplの場合、この回答は、実際のバイトコード(ソースからコンパイルされたある種の中間レベルまたは操作レベルのコードになる)ではなく、何が行われているのかについてのバイナリ算術解釈を示します。
パトリックM

5
@etruscoどの言語について話しているのですか?私は正確に0の場所を知っていますTrue == -1、そして私はそれが言える場所の多くを知っていTrue == 1ます...
l4mpi

1
@etrusco @ l4mpi一部の旧式のBASIC -1はTRUEを使用しています。あなたが短絡を気にしない限り、ビットANDおよびOR演算子が論理ANDおよびORでも機能するという優れた特性があります(Cではゼロでないx & -1場合と同じ場合x && 1はゼロではありません)。 。しかし、私の知る限りでは、主流の言語が-1TRUEに使用されたことはありません。
Quuxplusone 2014

1
形式的論理はtruth一価として定義します。すべてをされていないというtrueことfalse。私が知っているすべてのプログラミング言語は、頭に正式なロジックがあり、false一価(0)として定義されていますtrue。たとえば、C#の場合、JavaScriptは外れ値のようなものですが、複数の真実のフレーバー複数の偽造のフレーバーがあります。
ニコラスキャリー

45

Python bool型はのサブクラスですint(歴史的な理由により、ブール値はPython 2.3でのみ追加されました)。

以来int(True)1~Trueされ~1ています-2

がのサブクラスである理由については、PEP 285を参照してください。boolint

ブール逆演算が必要な場合は、次を使用しますnot

>>> not True
False
>>> not False
True

あなたは理由を知りたいと思った場合~1である-2あなたが符号付き整数のすべてのビットを反転しているので、それはです。00000001となり1111110にいるの符号付き整数の負の数である、参照2の補数を

>>> # Python 3
...
>>> import struct
>>> format(struct.pack('b', 1)[0], '08b')
'00000001'
>>> format(struct.pack('b', ~1)[0], '08b')
'11111110'

ここで、最初の1ビットは値が負であることを意味し、残りのビットは正の数から1を引いたものの逆数をエンコードします。


1
@GrijeshChauhan:2の賛辞struct.packとしてbin(integer)format(integer, '08b')符号付き整数を考慮に入れないで、または使用しないでください。
Martijn Pieters

@thefourtheye、私がしようとしたが、それは、例えばを混乱さMartijnPietersはbin(~True)bin(-2)bin(~1)すべてが与え'-0b10' た場合-2の表現があり10、なぜ-看板。
Grijesh Chauhan 14

10次に、2の補数-ve とはどういう意味ですか?
Grijesh Chauhan 14

1
@GrijeshChauhanこのように、負の数と正の数の両方の2の補数表記を取得できますformat(-2 % (1 << 32), "032b")
thefourtheye

2
@thefourtheye:ビットマスクを使用します:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters

4

~True == -2ビット単位の反転を意味し意味する場合 驚くことではありませんTrue1 ~ ...

... ただし、

  • True 整数として扱うことができ、
  • 整数は2の補数で表されます

編集:

  • 整数表現とビット単位の反転演算子の混合を修正
  • 別の洗練を適用しました(メッセージが短いほど、必要な作業が増えます)

2
~「2の補数」を意味するものではありません。~「ビットごとの反転」を意味します
マッケイ

1
「1の補数」という語句は、整数をビット単位で格納するシステムを指すのと同じくらい、実際には演算を指しません。コンピュータシステムで実際に使用されていないシステム。
マッケイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.