在 Lua 中使用 32 位按位运算比较有符号的 64 位数字 [英] Comparing signed 64 bit number using 32 bit bitwise operations in Lua

查看:49
本文介绍了在 Lua 中使用 32 位按位运算比较有符号的 64 位数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Lua on Redis and want to compare two signed 64-bit numbers, which are stored in two 8-byte/character strings.

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

How can I compare them using the libraries available in Redis? http://redis.io/commands/EVAL#available-libraries

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

I'd like to know >/< and == checks. I think this probably involves pulling two 32-bit numbers for each 64-bit int, and doing some clever math on those, but I am not sure.

我有一些代码可以使这不那么抽象.a0a1b0b1 都是用于表示 msb & 的 32 位数字.两个 64 位有符号整数 64s 的 lsb:

I have some code to make this less abstract. a0, a1, b0, b1 are all 32 bit numbers used to represent the msb & lsb's of two 64-bit signed int 64s:

-- ...
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))

添加代码

推荐答案

我想出了一个看起来有效的方法.不过有点丑.

I came up with a method that looks like it's working. It's a little ugly though.

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

The first step is to compare top 32 bits as 2 compliment #’s MSB sign bit stays, so numbers keep correct relations

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

所以从 MSB 的作品返回结果,除非它们相等,然后需要检查 LSB.

So returning the result from the MSB's works unless they are equal, then the LSB's need to get checked.

我有几个案例来建立一些模式:

I have a few cases to establish the some patterns:

-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 值,总是.

The sign bit on MSB’s doesn’t matter b/c negative numbers have the same relationship between themselves as positive numbers. e.g regardless of sign bit, lsb values of 0xff > 0xfe, always.

如果低 32 位的 MSB 不同怎么办?

What about if the MSB on the lower 32 bits is different?

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 位无符号适用于所有情况.

So we need to ignore the sign bit on the lower 32 bits. And since the relationships are the same for the LSBs regardless of sign, just using the lowest 32 bits unsigned works for all cases.

这意味着我想要为 MSB 签名,为 LSB 签名 - 因此将 I4 更改为 LSB 的 i4.还使 big endian 正式并在 struct.unpack 调用上使用>":

This means I want signed for the MSB's and unsigned for the LSBs - so chaging I4 to i4 for the LSBs. Also making big endian official and using '>' on the struct.unpack calls:

-- ...
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 中使用 32 位按位运算比较有符号的 64 位数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆