Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Membandingkan nomor 64 bit yang ditandatangani menggunakan operasi bitwise 32 bit di Lua

Saya menemukan metode yang sepertinya berhasil. Ini sedikit jelek.

Langkah pertama adalah membandingkan 32 bit teratas karena 2 bit tanda MSB pelengkap # tetap, jadi angka menjaga hubungan yang benar

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

Jadi mengembalikan hasil dari pekerjaan MSB kecuali sama, maka LSB perlu diperiksa.

Saya memiliki beberapa kasus untuk menetapkan beberapa pola:

-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

Dan

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 tanda pada MSB tidak masalah b/c angka negatif memiliki hubungan yang sama di antara mereka sebagai angka positif. misalnya terlepas dari bit tanda, nilai lsb 0xff> 0xfe , selalu.

Bagaimana jika MSB pada 32 bit yang lebih rendah berbeda?

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!

Jadi kita perlu mengabaikan tanda bit pada 32 bit yang lebih rendah. Dan karena hubungannya sama untuk LSB terlepas dari tandanya, hanya menggunakan 32 bit terendah yang tidak ditandatangani berfungsi untuk semua kasus.

Ini berarti saya ingin menandatangani untuk MSB dan tidak menandatangani untuk LSB - jadi chaging I4 ke i4 untuk LSB. Juga membuat big endian resmi dan menggunakan '>' pada panggilan 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. Cara menggunakan jackson alih-alih JdkSerializationRedisSerializer di musim semi

  2. Bagaimana Redis Streams menangani penggunaan semua memori yang tersedia?

  3. meneruskan hasil ke perintah lain di redis

  4. Redis benchmarking untuk perintah hget dan hset

  5. Konvensi penamaan kunci redis?