Чому ~ Істинний результат призводить до -2?


132

У консолі Python:

~True

Дає мені:

-2

Чому? Чи може хтось пояснити мені цей конкретний випадок у двійковій формі?


22
тому що ~1це -2, спробуйте:True == 1
Grijesh CHAUHAN

15
Щоб бути точним: це неправда " True is 1", але це правда True == 1.
Бах

3
Ви дійсно думаєте, що бачення UNARY_INVERT(весь байт-код) додасть щось у відповіді?
Wooble

2
Це питання не є дублікатом! Це запитує про конкретну поведінку bool. Справа не в тому, як це ~працює. Насправді правильна відповідь на це запитання могла б уникнути згадування про доповнення 2 та про те, як ~взагалі діє на цілі числа.
Бакуріу

Відповіді:


240

int(True)є 1.

1 є:

00000001

і ~1це:

11111110

Що -2в додатковому довічним 1

1 Переверніть всі біти, додайте 1 до отриманого числа та інтерпретуйте результат як двійкове подання величини та додайте від'ємний знак (оскільки число починається з 1):

11111110  00000001  00000010 
                    
       Flip       Add 1

Це 2, але знак негативний, оскільки MSB дорівнює 1.


Варто згадати:

Подумайте про те bool, ви виявите , що це числовий характер - має два значення, Trueі False, і вони просто «налаштовані» версія цілих чисел 1 і 0 , які тільки друкують себе по- різному. Вони є підкласами цілочисельного типу int.

Отже, вони поводяться точно як 1 і 0, за винятком того, що boolпереосмислюють strі reprвідображають їх по-різному.

>>> 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'бути виключенням типу помилки, тоді як ~Trueце не так, тому boolщо підклас int@ Martijn додав цю інформацію у свою відповідь.
Гріеш Чаухан

Для запису @ofcapl ця відповідь показує двійкову арифметичну інтерпретацію того, що відбувається, а не власне байт-код (який би був якийсь проміжний код або код рівня операції, зібраний з джерела).
Патрік М

5
@etrusco, якими мовами ти говориш? Я точно знаю 0, де True == -1, і я знаю багато, де можна сказати, що True == 1...
l4mpi

1
@etrusco @ l4mpi Деякі ОСНОВНІ старі школи використовують -1для ІСТИНИ ; вона має приємне властивість, що оператори бітового І та АБО працюють як для логічних, так і для АБО ( x & -1це не нульове значення в тих же випадках, що x && 1і в С), якщо ви не піклуєтесь про коротке замикання . Однак, наскільки я знаю, жодна основна мова ніколи не використовувалася -1для ІСТИНИ.
Quuxplusone

1
Формальна логіка визначається truthяк однозначна; з усім , що ні trueє false. Усі мови програмування, які я знаю, перетворюють формальну логіку на голову, визначаючи falseяк однозначну (0) і все, що не є фальшивим буттям true). Наприклад, C # , хоча Javascript - це щось чуже, що має безліч ароматів правдивості та декількох присмаків помилковості .
Ніколас Кері

45

Тип Python bool- це підклас int(з історичних причин; булеви були додані лише в Python 2.3).

Так як int(True)це 1, ~Trueце ~1є -2.

Дивіться PEP 285, чому boolце підклас int.

Якщо ви хотіли булевого зворотного, скористайтеся not:

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

Якщо ви хочете знати , чому ~1це -2, це тому , що ви инвертирования всіх бітів в знакове ціле число; 00000001стає 1111110котрим у підписане ціле число є від’ємним числом, див . доповнення двох :

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

де початковий 1біт означає значення негативне, а решта бітів кодують обернене додатне число мінус один.


1
@GrijeshChauhan: Для компліменту для двох ви можете використовувати struct.pack, як bin(integer)і format(integer, '08b')не брати до уваги цілі підписані числа.
Martijn Pieters

@thefourtheye, MartijnPieters я намагався , але це збиває з пантелику , наприклад bin(~True), bin(-2), bin(~1)все дає '-0b10' Якщо -2уявлення , 10то чому -знак.
Гріеш Чаухан

Що я маю на увазі під 10собою 2'доповнення тоді -ві?
Гріеш Чаухан

1
@GrijeshChauhan Ви можете отримати позначення доповнення двох як негативних, так і позитивних чисел, як цеformat(-2 % (1 << 32), "032b")
thefourtheye

2
@thefourtheye: Я б скористався бітмаскою:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters

4

~True == -2це не дивно , якщо True кошти 1 і ~ кошти побітовое звернення ...

... за умови, що

  • True може трактуватися як ціле число і
  • цілі числа представлені у доповненні Двох

Зміни:

  • фіксували змішування між цілим представленням і бітовим оператором інверсії
  • застосовано ще одне полірування (чим коротше повідомлення, тим більше роботи потрібно)

2
~не означає "доповнення 2s". ~означає "Побітова інверсія"
Маккей

1
Фраза "доповнення Онеса" насправді не стосується операції, наскільки вона стосується системи зберігання цілих чисел у бітах. Система, яка насправді не використовується в комп'ютерній системі.
Маккей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.