Tại sao ~ Kết quả đúng trong -2?


132

Trong bảng điều khiển Python:

~True

Đưa cho tôi:

-2

Tại sao? Ai đó có thể giải thích trường hợp cụ thể này cho tôi trong nhị phân?


22
~1-2, Hãy thử:True == 1
Grijesh Chauhan

15
Nói chính xác là: "không đúng True is 1", nhưng đúng là như vậy True == 1.
Bạch

3
Bạn có thực sự nghĩ rằng việc nhìn thấy UNARY_INVERT(toàn bộ mã byte) sẽ thêm bất cứ điều gì vào câu trả lời không?
Wooble

2
Câu hỏi này không phải là một bản sao! Nó hỏi về một hành vi cụ thể của bool. Nó không phải là về cách làm ~việc. Trong thực tế, một câu trả lời hợp lệ cho câu hỏi này có thể tránh đề cập đến phần bù 2 và cách ~hoạt động trên các số nguyên.
Bakuriu

Câu trả lời:


240

int(True)1.

1 Là:

00000001

~1là:

11111110

Đó là -2trong bổ sung Hai của 1

1 Lật tất cả các bit, thêm 1 vào số kết quả và diễn giải kết quả dưới dạng biểu diễn nhị phân của độ lớn và thêm dấu âm (vì số bắt đầu bằng 1):

11111110  00000001  00000010 
                    
       Flip       Add 1

Đó là 2, nhưng dấu là âm vì MSB là 1.


Đáng nói:

Hãy suy nghĩ về bool, bạn sẽ thấy rằng đó là số trong tự nhiên - Nó có hai giá trị, TrueFalse, và họ chỉ "tùy chỉnh" phiên bản của các số nguyên 1 và 0 mà chỉ in bản thân khác nhau. Chúng là các lớp con của kiểu số nguyên int.

Vì vậy, chúng hoạt động chính xác như 1 và 0, ngoại trừ boolxác định lại strreprhiển thị chúng khác nhau.

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

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

1
@ofcapl Chỉ muốn nói: Mặc dù int('1')cũng có 1nhưng ~'1'là một ngoại lệ của trình đánh máy trong khi đó ~Truekhông phải là vì đây boollà một lớp con của int@ Martijn đã thêm thông tin này vào câu trả lời của anh ấy.
Grijesh Chauhan

Đối với bản ghi, @ofcapl, câu trả lời này cho thấy cách hiểu số học nhị phân của những gì đang diễn ra, không phải mã byte thực tế (sẽ là một loại mã cấp độ trung gian hoặc hoạt động được biên dịch từ nguồn).
Patrick M

5
@etrusco bạn đang nói về ngôn ngữ nào? Tôi biết chính xác 0 ở đâu True == -1và tôi biết nhiều nơi người ta có thể nói rằng True == 1...
l4mpi

1
@etrusco @ l4mpi Một số BASIC trường học cũ sử dụng -1cho TRUE; nó có một đặc tính tốt là các toán tử bit AND và OR cũng hoạt động cho logic AND và OR ( x & -1không khác 0 trong cùng các trường hợp x && 1khác không trong C), miễn là bạn không quan tâm đến việc đoản mạch . Tuy nhiên, theo tôi biết, không có ngôn ngữ chính thống nào được sử dụng -1cho TRUE.
Quuxplusone

1
Logic hình thức được định nghĩa truthlà univalued; với tất cả những gì không trueđược false. Tất cả các ngôn ngữ lập trình mà tôi biết về việc biến logic chính thức trên đầu của nó, xác định falselà chưa hợp nhất (0) và tất cả những ngôn ngữ đó không phải là sai true). Ví dụ, C # , mặc dù Javascript là một thứ gì đó xa lạ, có nhiều hương vị của sự thật và nhiều hương vị giả .
Nicholas Carey

45

Kiểu Python boollà một lớp con của int(vì lý do lịch sử; booleans chỉ được thêm vào Python 2.3).

Kể từ khi int(True)1, ~True~1-2.

Xem PEP 285 để biết lý do tại sao boolmột lớp con của int.

Nếu bạn muốn nghịch đảo boolean, sử dụng not:

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

Nếu bạn muốn biết tại sao ~1-2, đó là vì bạn đang đảo ngược tất cả các bit trong một số nguyên đã ký kết; 00000001trở thành 1111110mà trong một số nguyên là một số âm, xem bổ sung Hai của :

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

trong đó 1bit ban đầu có nghĩa là giá trị âm và phần còn lại của bit mã hóa nghịch đảo của số dương trừ đi một.


1
@GrijeshChauhan: Đối với lời khen của hai người, bạn có thể sử dụng struct.pack, bin(integer)hoặc format(integer, '08b')không đưa số nguyên đã ký vào tài khoản.
Martijn Pieters

@thefourtheye, MartijnPieters Tôi đã thử Nhưng thật khó hiểu bin(~True), vd bin(-2), bin(~1)tất cả đều cho '-0b10' Nếu -2đại diện là 10tại sao lại -ký.
Grijesh Chauhan

Ý tôi là 10chính nó 2'compuity rồi -ve?
Grijesh Chauhan

1
@GrijeshChauhan Bạn có thể nhận được ký hiệu bổ sung của cả hai số âm và số dương như thế nàyformat(-2 % (1 << 32), "032b")
thefourtheye

2
@thefourtheye: Tôi sẽ sử dụng bitmask:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters

4

~True == -2không ngạc nhiên nếu True phương tiện 1 ~ phương tiện Bitwise đảo ngược ...

... miễn là

  • True có thể được coi là một số nguyên và
  • số nguyên được biểu diễn trong phần bù của Two

Chỉnh sửa:

  • đã sửa lỗi trộn giữa biểu diễn số nguyên và toán tử đảo ngược bitwise
  • áp dụng một đánh bóng khác (tin nhắn càng ngắn, càng cần nhiều công việc)

2
~không có nghĩa là "bổ sung 2s". ~có nghĩa là "Đảo ngược bitwise"
McKay

1
Cụm từ "Bổ sung của Ones" không thực sự đề cập đến một hoạt động, nhiều như nó đề cập đến một hệ thống lưu trữ số nguyên theo bit. Một hệ thống không thực sự được sử dụng trong một hệ thống máy tính.
McKay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.