sql >> Database teknologi >  >> NoSQL >> Redis

Sammenligning af fortegnet 64 bit nummer ved hjælp af 32 bit bitvise operationer i Lua

Jeg fandt på en metode, der ser ud til at virke. Det er dog lidt grimt.

Det første trin er at sammenligne de øverste 32 bits som 2 kompliment #'sMSB-tegnbit forbliver, så tal holder korrekte relationer

-1  —> -1
0 —> 0
9223372036854775807 = 0x7fff ffff ffff ffff -> 0x7ffff ffff = 2147483647

Så returnerer man resultatet fra MSB's værker, medmindre de er ens, så er LSB's behov for at blive tjekket.

Jeg har et par tilfælde til at etablere nogle mønstre:

-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

Og

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

Fortegnsbitten på MSB'er er ligegyldig b/c negative tal har samme forhold indbyrdes som positive tal. fx uanset fortegnsbit, lsb-værdier af 0xff> 0xfe , altid.

Hvad hvis MSB'en på de nederste 32 bit er anderledes?

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!

Så vi er nødt til at ignorere fortegnsbitten på de nederste 32 bits. Og da relationerne er de samme for LSB'erne uanset fortegn, virker bare at bruge de laveste 32 bit usignerede for alle tilfælde.

Det betyder, at jeg vil have signeret for MSB'erne og usigneret for LSB'erne - så ændrer I4 til i4 for LSB'erne. Gør også big endian officiel og bruger '>' på struct.unpack-kaldene:

-- ...
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))


  1. MongoDB og C#:Uafhængig søgning

  2. Kan jeg forespørge MongoDB ObjectId efter dato?

  3. Kom godt i gang med PHP og MongoDB

  4. Brugerdefinerede funktioner beregnede kolonner mongodb projektion