sql >> データベース >  >> NoSQL >> Redis

Luaで32ビットビット演算を使用して符号付き64ビット数を比較する

    私はそれが機能しているように見える方法を思いついた。でも少し醜いです。

    最初のステップは、2つの補数#のMSB符号ビットが残っているため、上位32ビットを比較することです。これにより、数値は正しい関係を維持します

    -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の符号ビットは重要ではありません。b/cの負の数は、正の数と同じ関係にあります。たとえば、符号ビットに関係なく、0xffのlsb値> 0xfe 、常に。

    下位32ビットのMSBが異なる場合はどうでしょうか?

    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. リレーショナルDBがメモリ内にありますか?

    3. Redisのデータディレクトリはどこにありますか?

    4. MongoDB $ sqrt