Mengapa ~ Benar menghasilkan -2?

132

Di konsol Python:

~True

Memberi saya:

-2

Mengapa? Bisakah seseorang menjelaskan kasus khusus ini kepada saya dalam bentuk biner?

lukaszkups
sumber
22
karena ~1adalah -2, Coba:True == 1
Grijesh Chauhan
15
Tepatnya: " True is 1" itu tidak benar , tetapi itu benar True == 1.
Bach
3
Apakah Anda benar-benar berpikir melihat UNARY_INVERT(seluruh bytecode) akan menambah sesuatu pada jawaban?
Wooble
2
Pertanyaan ini bukan duplikat! Ia bertanya tentang perilaku spesifik bool. Ini bukan tentang cara ~kerjanya. Sebenarnya jawaban yang valid untuk pertanyaan ini dapat menghindari menyebutkan komplemen 2 dan bagaimana ~beroperasi pada bilangan bulat sama sekali.
Bakuriu

Jawaban:

240

int(True)adalah 1.

1 adalah:

00000001

dan ~1adalah:

11111110

Yang ada -2di komplemen Two's 1

1 Balik semua bit, tambahkan 1 ke angka yang dihasilkan dan interpretasikan hasilnya sebagai representasi biner dari besarnya dan tambahkan tanda negatif (karena angka dimulai dengan 1):

11111110  00000001  00000010 
                    
       Flip       Add 1

Yang 2, tetapi tandanya negatif karena MSB adalah 1.


Layak disebut:

Pikirkan bool, Anda akan menemukan bahwa itu sifatnya numerik - Ini memiliki dua nilai, Truedan False, dan itu hanyalah versi "khusus" dari bilangan bulat 1 dan 0 yang hanya mencetak diri mereka secara berbeda. Mereka adalah subclass dari tipe integer int.

Jadi mereka berperilaku tepat seperti 1 dan 0, kecuali itu boolmendefinisikan ulang strdan reprmenampilkannya secara berbeda.

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

>>> True == 1
True
>>> True is 1  # they're still different objects
False
Maroun
sumber
1
@ofcapl Hanya ingin mengatakan: Meskipun int('1')juga 1tetapi ~'1'menjadi typeerror exception sedangkan ~Truebukankah ini karena boolsubclass dari int@ Martijn menambahkan informasi ini dalam jawabannya.
Grijesh Chauhan
Sebagai catatan, @ofcapl, jawaban ini menunjukkan interpretasi aritmatika biner dari apa yang terjadi, bukan bytecode yang sebenarnya (yang akan menjadi semacam kode tingkat menengah atau operasi yang dikompilasi dari sumber).
Patrick M
5
@etrusco bahasa apa yang Anda bicarakan? Saya tahu persis 0 di mana True == -1, dan saya tahu banyak di mana orang dapat mengatakan bahwa True == 1...
14mpi
1
@etrusco @ l4mpi Beberapa BASIC jadul digunakan -1untuk BENAR; ia memiliki properti bagus yang bitwise AND dan OR operator bekerja untuk logika AND dan OR juga ( x & -1tidak nol dalam kasus yang sama yang x && 1tidak nol dalam C), selama Anda tidak peduli tentang hubungan arus pendek . Namun, sejauh yang saya tahu, tidak ada bahasa utama yang pernah digunakan -1untuk TRUE.
Quuxplusone
1
Logika formal didefinisikan truthsebagai tidak bernilai; dengan semua yang tidak trueada false. Semua bahasa pemrograman yang saya sadari mengubah logika formal di atas kepalanya, mendefinisikan falsesebagai tidak bernilai (0) dan semua yang tidak salah adalah true). Misalnya C # , meskipun Javascript adalah sesuatu yang outlier, memiliki beberapa rasa kebenaran dan banyak rasa kepalsuan .
Nicholas Carey
45

boolTipe Python adalah subkelas dari int(karena alasan historis; boolean hanya ditambahkan dalam Python 2.3).

Sejak int(True)adalah 1, ~Trueadalah ~1adalah -2.

Lihat PEP 285 untuk alasan mengapa boolsubclass dari int.

Jika Anda menginginkan boolean invers, gunakan not:

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

Jika Anda ingin tahu mengapa ~1adalah -2, itu karena Anda pembalik semua bit dalam bilangan bulat ditandatangani; 00000001menjadi 1111110yang dalam bilangan bulat yang ditandatangani adalah angka negatif, lihat komplemen Dua :

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

di mana 1bit awal berarti nilainya negatif, dan sisa bit mengkodekan kebalikan dari angka positif dikurangi satu.

Martijn Pieters
sumber
1
@GrijeshChauhan: Untuk pujian dua orang, Anda dapat menggunakan struct.pack, sebagai bin(integer)atau format(integer, '08b')tidak memperhitungkan bilangan bulat yang ditandatangani.
Martijn Pieters
@thefourtheye, MartijnPieters saya Mencoba Tapi itu membingungkan misalnya bin(~True), bin(-2), bin(~1)semua memberi '-0b10' Jika -2representasi adalah 10mengapa -tanda.
Grijesh Chauhan
Apa yang saya maksud dengan 10sendirinya?
Grijesh Chauhan
1
@GrijeshChauhan Anda bisa mendapatkan notasi pelengkap keduanya dari angka negatif dan positif seperti iniformat(-2 % (1 << 32), "032b")
thefourtheye
2
@thefourtheye: Saya akan menggunakan bitmask:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters
4

~True == -2adalah tidak mengejutkan jika True sarana 1 dan ~ sarana bitwise inversi ...

... asalkan itu

  • True dapat diperlakukan sebagai bilangan bulat dan
  • bilangan bulat diwakili dalam komplemen Dua

Suntingan:

  • memperbaiki pencampuran antara representasi integer dan operator inversi bitwise
  • menerapkan pemolesan lain (semakin pendek pesannya, semakin banyak pekerjaan yang dibutuhkan)
Serigala
sumber
2
~tidak berarti "komplemen 2s". ~berarti "Pembalikan Bitwise"
McKay
1
Ungkapan "Komplemen satu" tidak benar-benar merujuk pada operasi, sebanyak mengacu pada sistem menyimpan bilangan bulat dalam bit. Sistem yang sebenarnya tidak digunakan dalam sistem komputer.
McKay