
有如下 C 代码:
#include <stdio.h> int main() { int x = 0x87654321; int mask = 0xFF; printf("0x%08x\n", ~mask); printf("0x%08x\n", x & mask); printf("0x%08x\n", x ^ ~mask); printf("0x%08x\n", x | mask); return 0; } 输出:
0xffffff00 0x00000021 0x789abc21 0x876543ff 改成对应的 python 代码:
x = 0x87654321 mask = 0xFF print("0x%08x" % (~mask)) print("0x%08x" % (x & mask)) print("0x%08x" % (x ^ ~mask)) print("0x%08x" % (x | mask)) 输出:
0x-0000100 0x00000021 0x-876543df 0x876543ff 请问 python 输出与 C 输出不一致的原因是什么,能否修改 python 代码使其与 C 输出一致?
1 pright 2017-06-19 17:28:25 +08:00 import ctypes print("0x%08x" % (ctypes.c_uint(~mask).value)) |
2 enenaaa 2017-06-19 17:48:12 +08:00 好像是被当成有符号数打印了。 试一下 &0xffffffff。这样 print("0x%08x" % ((~mask)&0xffffffff)) |
3 popstk 2017-06-19 17:54:49 +08:00 <code>def foo(n, size=32): return ((1<<size)-1)&n x = 0x87654321 mask = 0xFF print("0x%08x" % foo(~mask)) print("0x%08x" % foo(x & mask)) print("0x%08x" % foo(x ^ ~mask)) print("0x%08x" % foo(x | mask)) </code> https://wiki.python.org/moin/BitwiseOperators |
4 NoAnyLove 2017-06-20 00:48:15 +08:00 因为 Python 的 int 是无限长度的,如果对一个正整数取反,会变成负数,你可以认为符号位是无限长度的 1: ``` >>> mask = 0xFF >>> bin(mask) '0b11111111' >>> ~mask -256 >>> bin(~mask) '-0b100000000' ``` `bin(~mask)`返回结果'-0b100000000',前面的`-0`就是相当于无限长度的符号位,如果用 Two ‘ s Complement 来表示就全是 1. 解决这个问题也很简单,将结果按位与 0xFFFFFFFF (刚好 32 位 bit )运算,就可以消除掉超过 32 位的无限长度的符号位。 ``` >>> ~mask & 0xFFFFFFFF 4294967040 >>> hex(_) '0xffffff00' ``` |
5 justou OP 感谢楼上各位,4L 给了个很好的解释 |
6 pright 2017-06-20 14:10:35 +08:00 这里不一致的原因其实就是 C 的 printf 的%x 对应的是 unsigned hexadecimal integer,而 python 的 print 的%x 对应的是 signed hexadecimal integer。 |