按位 NOT
~
運算子將翻轉數字中的所有位。由於計算機使用有符號數表示 - 最值得注意的是,二進位制補碼錶示編碼負二進位制數,其中負數用前導(1)而不是前導零(0)寫入。
這意味著如果你使用 8 位來表示二進位制補碼數,則可以將 0000 0000
到 0111 1111
的模式表示為 0 到 127 之間的數字,並保留 1xxx xxxx
來表示負數。
八位二進位制補碼數
位 | 無符號值 | 二進位制補碼值 |
---|---|---|
0000 0000 | 0 | 0 |
0000 0001 | 1 | 1 |
0000 0010 | 2 | 2 |
0111 1110 | 126 | 126 |
0111 1111 | 127 | 127 |
1000 0000 | 128 | -128 |
1000 0001 | 129 | -127 |
1000 0010 | 130 | -126 |
1111 1110 | 254 | -2 |
1111 1111 | 255 | -1 |
實質上,這意味著雖然 1010 0110
的無符號值為 166(通過新增 (128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0)
得到),但它的二進位制補碼值為 -90(通過新增 (128 * 1) - (64 * 0) - (32 * 1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0)
得到,並補充該值)。
通過這種方式,負數範圍可以達到 -128(1000 0000
)。零(0)表示為 0000 0000
,減 1(-1)表示為 1111 1111
。
但總的來說,這意味著~n = -n - 1
。
# 0 = 0b0000 0000
~0
# Out: -1
# -1 = 0b1111 1111
# 1 = 0b0000 0001
~1
# Out: -2
# -2 = 1111 1110
# 2 = 0b0000 0010
~2
# Out: -3
# -3 = 0b1111 1101
# 123 = 0b0111 1011
~123
# Out: -124
# -124 = 0b1000 0100
注意,當應用於正數時,此操作的總體效果可以歸納為:
~n -> -|n+1|
然後,當應用於負數時,相應的效果是:
~-n -> |n-1|
以下示例說明了最後一條規則……
# -0 = 0b0000 0000
~-0
# Out: -1
# -1 = 0b1111 1111
# 0 is the obvious exception to this rule, as -0 == 0 always
# -1 = 0b1000 0001
~-1
# Out: 0
# 0 = 0b0000 0000
# -2 = 0b1111 1110
~-2
# Out: 1
# 1 = 0b0000 0001
# -123 = 0b1111 1011
~-123
# Out: 122
# 122 = 0b0111 1010