sql >> Database >  >> NoSQL >> Redis

Ondertekend 64-bits nummer vergelijken met 32-bits bitsgewijze bewerkingen in Lua

Ik heb een methode bedacht die lijkt te werken. Het is wel een beetje lelijk.

De eerste stap is om de top 32 bits te vergelijken, aangezien het MSB-tekenbit van 2 compliment #'s blijft staan, zodat de getallen de juiste relaties behouden

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

Dus het resultaat van de werken van de MSB retourneren, tenzij ze gelijk zijn, dan moeten de LSB's worden gecontroleerd.

Ik heb een paar gevallen om de patronen vast te stellen:

-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

En

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

Het tekenbit op MSB's doet er niet toe, want negatieve getallen hebben dezelfde relatie als positieve getallen. bijv. ongeacht tekenbit, lsb-waarden van 0xff> 0xfe , altijd.

Hoe zit het als de MSB op de onderste 32 bits anders is?

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!

Dus we moeten het tekenbit op de onderste 32 bits negeren. En aangezien de relaties hetzelfde zijn voor de LSB's, ongeacht het teken, werkt het gebruik van de laagste 32 bits niet-ondertekend in alle gevallen.

Dit betekent dat ik getekend wil hebben voor de MSB's en niet getekend voor de LSB's - dus I4 wijzigen naar i4 voor de LSB's. Ook big endian officieel maken en '>' gebruiken bij de struct.unpack-aanroepen:

-- ...
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. Wat is het voordeel van het gebruik van de aangepaste backend van Gorilla-sessies?

  2. MongoDB installeren en configureren op Ubuntu

  3. Hoe update-bewerkingen in GridFS uitvoeren (met Java)?

  4. Verschil tussen Find en FindAsync