lua - 在 Lua 中使用 32 位按位运算比较带符号的 64 位数

标签 lua redis

我在 Redis 上使用 Lua,想比较两个有符号的 64 位数字,它们存储在两个 8 字节/字符串中。

如何使用 Redis 中可用的库比较它们? http://redis.io/commands/EVAL#available-libraries

我想知道>/<==检查。我认为这可能涉及为每个 64 位整数提取两个 32 位数字,并对它们进行一些巧妙的数学运算,但我不确定。

我有一些代码可以使它不那么抽象。 a0 , a1 , b0 , b1都是用于表示两个 64 位带符号整数 64 的 msb 和 lsb 的所有 32 位数字:

-- ...
local comp_int64s = function (a0, a1, b0, b1)
    local cmpres = 0
    -- TOOD: Real comparison
    return cmpres
end
local l, a0, a1, b0, b1
a0, l = bit.tobit(struct.unpack("I4", ARGV[1]))
a1, l = bit.tobit(struct.unpack("I4", ARGV[1], 5))
b0, l = bit.tobit(struct.unpack("I4", blob))
b1, l = bit.tobit(struct.unpack("I4", blob, 5))
print("Cmp result", comp_int64s(a0, a1, b0, b1))

编辑:添加代码

最佳答案

我想出了一个看起来很有效的方法。虽然有点丑。

第一步是比较前 32 位作为 2 个补码# MSB 符号位保留,所以数字保持正确的关系

-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 > 0xfe 的 lsb 值始终如此。

如果低 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 进行未签名 - 因此将 LSB 的 I4 更改为 i4。还使 big endian 正式化并在 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))

关于lua - 在 Lua 中使用 32 位按位运算比较带符号的 64 位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35488855/

相关文章:

C - 脚本在程序中应该做什么

C++ 使用 loadbuffer 和 runbuffer 链接和运行 LuaJit 编译文件

redis - 当主服务器宕机时,Redis群集恢复停机时间

macos - 在 Bash 中处理依赖进程

javascript - Redis 数据库设计不当

java - 如何使用 ElastiCache 作为 Camel 幂等存储库?

Lua:获取默认小于数字的函数

lua -> 如何将这些参数修改为 const,或者我应该做什么?

redis - 在分层数据模型中使用 Redis 进行复合索引

c++ - Lua C API : Retrieve values from Lua function returning a table in C code