Eu vim com um método que parece que está funcionando. Mas é um pouco feio.
O primeiro passo é comparar os 32 bits principais, pois 2 bits de sinal MSB do elogio permanecem, para que os números mantenham as relações corretas
-1 —> -1
0 —> 0
9223372036854775807 = 0x7fff ffff ffff ffff -> 0x7ffff ffff = 2147483647
Portanto, retornando o resultado dos trabalhos do MSB, a menos que sejam iguais, o LSB precisa ser verificado.
Eu tenho alguns casos para estabelecer alguns padrões:
-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
E
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
O bit de sinal nos MSBs não importa porque os números negativos têm a mesma relação entre si que os números positivos. por exemplo, independentemente do bit de sinal, valores lsb de
0xff
> 0xfe
, sempre. E se o MSB nos 32 bits inferiores for diferente?
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!
Portanto, precisamos ignorar o bit de sinal nos 32 bits inferiores. E como as relações são as mesmas para os LSBs, independentemente do sinal, basta usar os 32 bits mais baixos sem sinal para todos os casos.
Isso significa que eu quero assinado para os MSBs e não assinado para os LSBs - então alterando
I4
para i4
para os LSB. Também oficializando o big endian e usando '>' nas chamadas 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))