为个小善——发布 Python 库 absolute32
- 非狐外传 - 赖勇浩的编程私伙局赖勇浩(http://laiyonghao.com). 在较新版本的 Python 中,当两个 int 相加溢出时,它会自动把把结果转换到 long 类型,比如:. 这个特性很好,但是它跟 C 语言的结果不一样. 如果你要把结果 pack 到 4 个字节的 buffer 中发送到别的进程,结果就比较纠结:.
>>> 0x7FFFFFFF + 1 2147483648L这个特性很好,但是它跟 C 语言的结果不一样。如果你要把结果 pack 到 4 个字节的 buffer 中发送到别的进程,结果就比较纠结:
>>> import struct >>> struct.pack("i", 0x7FFFFFFF + 1) Traceback (most recent call last): File "<stdin>", line 1, in <module> struct.error: long too large to convert to int我在设计我的 webgame 网络协议时遇到了这个问题。
>>> hash('copyright' * 10) # 32-bit platform -942199392 >>> hash('copyright' * 10) # 64-bit platform -6555514777893392992想像一下你在 32-bit 下写了一个 k/v 存储的文件放到 64-bit 去读,或者反过来,是不是让你很抓狂?
Changed in version 2.6: The return value is in the range [-2**31, 2**31-1] regardless of platform. In older versions the value is signed on some platforms and unsigned on others.看到了吧,zlib.crc32(及 zlib.adler32) 虽然跟 32/64 位平台无关,但是 3.x 和 2.x 版本的返回值范围是不一致的,想象一下你设计的网络协议采用了 crc/adler 算法来计算 checksum,然后用于 3.x 和 2.x 版本的 Python 程序通信,会不会想抓狂呢?
Changed in version 3.0: The return value is unsigned and in the range [0, 2**32-1] regardless of platform.
easy_install -U absolute32就安装好啦,最后送上示例,享用吧,亲!
import absolute32 as a assert a.add(0x7FFFFFFF, 2) == -0x7FFFFFFF assert a.hash('copyright') == -174803930 assert a.adler(b'copyright') == 322503642 assert a.crc(b'copyright') == 947983859