Perché ~ True risulta in -2?


132

Nella console di Python:

~True

Mi da:

-2

Perché? Qualcuno può spiegarmi questo caso particolare in binario?


22
perché ~1è -2, prova:True == 1
Grijesh Chauhan,

15
Giusto per essere precisi: non è vero che " True is 1", ma è vero True == 1.
Bach,

3
Pensi davvero che vedere UNARY_INVERT(l'intero bytecode) aggiungerà qualcosa alle risposte?
Wooble,

2
Questa domanda non è un duplicato! Si chiede un comportamento specifico di bool. Non si tratta di come ~funziona. In effetti una risposta valida a questa domanda potrebbe evitare di menzionare il complemento di 2 e il modo in cui ~opera su numeri interi.
Bakuriu,

Risposte:


240

int(True)lo è 1.

1 è:

00000001

ed ~1è:

11111110

Che è -2nel complemento di Two 1

1 Capovolgi tutti i bit, aggiungi 1 al numero risultante e interpreta il risultato come una rappresentazione binaria della grandezza e aggiungi un segno negativo (poiché il numero inizia con 1):

11111110  00000001  00000010 
                    
       Flip       Add 1

Che è 2, ma il segno è negativo poiché l' MSB è 1.


Vale la pena citare:

Pensaci bool, scoprirai che è di natura numerica - Ha due valori Truee False, e sono solo versioni "personalizzate" degli interi 1 e 0 che si stampano solo in modo diverso. Sono sottoclassi del tipo intero int.

Quindi si comportano esattamente come 1 e 0, tranne per il fatto che li boolridefinisce stre reprli visualizza in modo diverso.

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

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

1
@ofcapl Volevo solo dire: sebbene int('1')sia anche, 1ma ~'1'sia un'eccezione tipografica, mentre ~Truenon lo è perché boolè una sottoclasse di int@ Martijn che ha aggiunto queste informazioni nella sua risposta.
Grijesh Chauhan,

Per la cronaca, @ofcapl, questa risposta mostra l'interpretazione aritmetica binaria di ciò che sta succedendo, non il bytecode effettivo (che sarebbe una sorta di codice di livello intermedio o operativo compilato dal sorgente).
Patrick M,

5
@etrusco di quali lingue stai parlando? So esattamente 0 dove True == -1, e so molti dove si potrebbe dire che True == 1...
l4mpi

1
@etrusco @ l4mpi Alcuni BASIC di vecchia scuola usano -1per TRUE; ha la bella proprietà che gli operatori AND bit OR e bit funzionano anche per AND logici e OR ( x & -1è diverso da zero negli stessi casi che x && 1è diverso da zero in C), purché non ti interessi il cortocircuito . Tuttavia, per quanto ne so, nessun linguaggio tradizionale ha mai usato -1per VERO.
Quuxplusone,

1
La logica formale definisce truthcome non valutata; con tutto ciò che non è trueessere false. Tutti i linguaggi di programmazione di cui sono a conoscenza trasformano la logica formale nella sua testa, definendola falsecome non valutata (0) e tutto ciò che non è falso essere true). Ad esempio C # , sebbene Javascript sia qualcosa di più anomalo, con molteplici gusti di verità e molteplici sapori di falsità .
Nicholas Carey,

45

Il booltipo Python è una sottoclasse diint (per motivi storici; i booleani sono stati aggiunti solo in Python 2.3).

Poiché int(True)è 1, ~Trueè ~1è-2 .

Vedi PEP 285 per quale boolè una sottoclasse diint .

Se si desidera l'inverso booleano, utilizzare not:

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

Se si voleva sapere perché ~1è -2, è perché si sta invertendo tutti i bit in un intero con segno; 00000001diventa 1111110, che in un firmato intero è un numero negativo, vedi complemento a due :

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

dove il 1bit iniziale indica che il valore è negativo e il resto dei bit codifica l'inverso del numero positivo meno uno.


1
@GrijeshChauhan: per il complimento di due, potresti usare struct.pack, come bin(integer)o format(integer, '08b')non prendere in considerazione numeri interi firmati.
Martijn Pieters

@thefourtheye, MartijnPieters Ho provato Ma è confuso bin(~True), per esempio bin(-2), bin(~1)tutto dà '-0b10' Se la -2rappresentazione è 10allora perché -firmare.
Grijesh Chauhan,

Cosa intendo per 10se stessa, allora complemento?
Grijesh Chauhan,

1
@GrijeshChauhan Puoi ottenere la notazione del complemento a due di entrambi i numeri negativi e positivi come questoformat(-2 % (1 << 32), "032b")
thefourtheye,

2
@thefourtheye: userei una maschera di bit:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters

4

~True == -2è non è sorprendente se True i mezzi 1 e ~ mezzi di inversione bit per bit ...

... purché

  • True può essere trattato come un numero intero e
  • i numeri interi sono rappresentati nel complemento di Two

modifiche:

  • corretto il mix tra rappresentazione di numero intero e operatore di inversione bit per bit
  • applicato un'altra lucidatura (più breve è il messaggio, più lavoro è necessario)

2
~non significa "complemento a 2 secondi". ~significa "Bitwise Inversion"
McKay,

1
La frase "complemento a Ones" non si riferisce realmente a un'operazione, quanto a un sistema di memorizzazione di numeri interi in bit. Un sistema che non è effettivamente utilizzato in un sistema informatico.
McKay,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.