Tôi đã nghĩ ra một phương pháp có vẻ như nó đang hoạt động. Nó hơi xấu một chút.
Bước đầu tiên là so sánh 32 bit trên cùng khi 2 bit dấu hiệu sMSB của # 'vẫn được giữ nguyên, vì vậy các số giữ quan hệ chính xác
-1 —> -1
0 —> 0
9223372036854775807 = 0x7fff ffff ffff ffff -> 0x7ffff ffff = 2147483647
Vì vậy, trả về kết quả từ các công việc của MSB trừ khi chúng bằng nhau, khi đó LSB cần phải được kiểm tra.
Tôi có một số trường hợp cần thiết lập một số mẫu:
-1 = 0xffff ffff ffff ffff
-2 = 0xffff ffff ffff fffe
32 bit is:
-1 -> 0xffff ffff = -1
-2 -> 0xffff fffe = -2
-1 > -2 would be like -1 > -2 : GOOD
Và
8589934591 = 0x0000 0001 ffff ffff
8589934590 = 0x0000 0001 ffff fffe
32 bit is:
8589934591 -> ffff ffff = -1
8589934590 -> ffff fffe = -2
8589934591 > 8589934590 would be -1 > -2 : GOOD
Bit dấu trên MSB không quan trọng b / c các số âm có cùng mối quan hệ giữa chúng với nhau như các số dương. ví dụ:bất kể bit dấu, giá trị lsb của 0xff
> 0xfe
, luôn luôn.
Còn nếu MSB trên 32 bit thấp hơn thì sao?
0xff7f ffff 7fff ffff = -36,028,799,166,447,617
0xff7f ffff ffff ffff = -36,028,797,018,963,969
32 bit is:
-..799.. -> 0x7fff ffff = 2147483647
-..797.. -> 0xffff ffff = -1
-..799.. < -..797.. would be 2147483647 < -1 : BAD!
Vì vậy chúng ta cần bỏ qua bit dấu trên 32 bit thấp hơn. Và vì các mối quan hệ giống nhau đối với các LSB bất kể dấu hiệu, chỉ cần sử dụng 32 bit thấp nhất không dấu sẽ hoạt động cho mọi trường hợp.
Điều này có nghĩa là tôi muốn ký tên cho MSB và chưa ký cho các LSB - vì vậy chaging I4
thành i4
cho LSB. Cũng làm cho endian chính thức lớn và sử dụng '>' trên các cuộc gọi struct.unpack:
-- ...
local comp_int64s = function (as0, au1, bs0, bu1)
if as0 > bs0 then
return 1
elseif as0 < bs0 then
return -1
else
-- msb's equal comparing lsbs - these are unsigned
if au1 > bu1 then
return 1
elseif au1 < bu1 then
return -1
else
return 0
end
end
end
local l, as0, au1, bs0, bu1
as0, l = bit.tobit(struct.unpack(">i4", ARGV[1]))
au1, l = bit.tobit(struct.unpack(">I4", ARGV[1], 5))
bs0, l = bit.tobit(struct.unpack(">i4", blob))
bu1, l = bit.tobit(struct.unpack(">I4", blob, 5))
print("Cmp result", comp_int64s(as0, au1, bs0, bu1))