要满足排序要求,您需要:
- 使用大端表示
- 如果符号位为 0,则将其翻转为 1。检查实际位 - 将原始数字与 0 进行比较在特殊情况下(例如负零)会得到不同的结果。
- 如果符号位为 1,则翻转所有位
Python 3 代码:
import struct
def invert(x):
return bytes(c ^ 255 for c in x)
def tobin(x):
binx = struct.pack('>d', x)
if binx > b'\x80': #negative
return invert(binx)
else:
return struct.pack('>d', -x)
data = [float('-inf'), -100.0, -2.0, -.9, -.1, -0.0,
0.0, .1, .9, 2.0, 100.0, float('inf'), float('nan')]
print(sorted(data, key=tobin))
#[-inf, -100.0, -2.0, -0.9, -0.1, -0.0, 0.0, 0.1, 0.9, 2.0, 100.0, inf, nan]
在 Python 2 上更改invert
为:
def invert(x):
return "".join(chr(ord(c) ^ 255) for c in x)
作为参考,这里是等效的 node.js,它已经通过 'Buffer' 类实现了 Big Endian 序列化功能:
function serialize(n) {
var buffer = new Buffer(8);
var l = buffer.length;
buffer.writeDoubleBE(n, 0);
if (buffer[0] < 0x80) {
buffer[0] ^= 0x80;
} else {
for (var i = 0; i < l; i++)
buffer[i] ^= 0xff;
}
return buffer
}
function deserialize(buffer) {
var l = buffer.length;
// 0x80 is the most significant byte of the representation of
// the first positive number(Number.MIN_VALUE)
if (buffer[0] >= 0x80) {
buffer[0] ^= 0x80;
} else {
for (var i = 0; i < l; i++)
buffer[i] ^= 0xff;
}
return buffer.readDoubleBE(0);
}