Redis
 sql >> база данни >  >> NoSQL >> Redis

Сравняване на 64-битово число със знак с помощта на 32-битови операции в Lua

Измислих метод, който изглежда работи. Все пак е малко грозно.

Първата стъпка е да се сравнят първите 32 бита като 2 комплимента #’sMSB знак бит остава, така че числата да поддържат правилни отношения

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

Така че връщането на резултата от работата на MSB освен ако не са равни, тогава LSB трябва да бъде проверен.

Имам няколко случая, за да установя някои модели:

-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

И

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

Знаковият бит на MSB няма значение, тъй като отрицателните числа имат същата връзка помежду си като положителните числа. например независимо от знаковия бит, lsb стойности на 0xff> 0xfe , винаги.

Ами ако MSB на по-ниските 32 бита е различен?

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!

Така че трябва да игнорираме знака на долните 32 бита. И тъй като връзките са едни и същи за LSB независимо от знака, само използването на най-ниските 32 бита без знак работи за всички случаи.

Това означава, че искам подписан за MSB и неподписан за LSB - така че променям I4 към i4 за LSB. Също така да направите официален голям байт и да използвате '>' в извикванията на 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))


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Разбиране на латентността с помощта на Redis-Cli

  2. Как да се свържете с Redis екземпляр (memorystore) от стандартния App Engine на Google (Python 3.7)

  3. Надеждни библиотеки за интеграционни тестове за Spring boot redis

  4. Как да отмените задание на опашка в Laravel или Redis

  5. Spring Redis - Прочетете конфигурацията от файла application.properties