有如下 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 1
import ctypes
print("0x%08x" % (ctypes.c_uint(~mask).value)) |
2
enenaaa 2017-06-19 17:48:12 +08:00 1
好像是被当成有符号数打印了。
试一下 &0xffffffff。这样 print("0x%08x" % ((~mask)&0xffffffff)) |
3
popstk 2017-06-19 17:54:49 +08:00 1
<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 3
因为 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。
|