Lua中检测32位序号环绕的方法

Lua中检测32位序号环绕的方法

lua 复制代码
--[[
    判断32位无符号序号a是否比b新(处理环绕)
    返回 true 表示a比b新,false 表示a比b旧或相等
--]]

--- 32位无符号时间戳升序比较器(处理回绕)
--- 判断 a 是否应该排在 b 前面,即 a 是否比 b 旧
--- @param a number 32位无符号整数
--- @param b number 32位无符号整数
--- @return boolean true 表示 a 比 b 旧,应排在前面
local function TimeComparator_Asc(a, b)
    if a == b then
        return false
    end
    -- 确保作为32位无符号数处理
    local a32 = a & 0xFFFFFFFF
    local b32 = b & 0xFFFFFFFF
    -- 计算 (a - b) mod 2^32
    local diff = (a32 - b32) & 0xFFFFFFFF
    -- 升序排序条件:如果 a 比 b 旧,则 (a - b) 的差值落在 [2^31, 2^32)
    -- 此时 diff >= 2^31
    return diff >= 0x80000000  -- 0x80000000 = 2^31
end

-- 方法一:取模运算(兼容 Lua 5.1+)
function is_newer_mod(a, b)
    local diff = (a - b) % 2^32
    return diff > 0 and diff < 2^31   -- 排除相等情况
end

-- 方法二:位运算(Lua 5.3+,效率更高)
function is_newer_bit(a, b)
    local a32 = a & 0xFFFFFFFF
    local b32 = b & 0xFFFFFFFF
    local diff = (a32 - b32) & 0xFFFFFFFF
    return diff ~= 0 and diff < 0x80000000  -- 0x80000000 = 2^31
end

-- 测试代码
local tests = {
    {100, 50, true},          -- 正常:100 > 50
    {50, 100, false},         -- 正常:50 < 100
    {1, 2^32-1, true},        -- 环绕:1 比 4294967295 新
    {2^32-1, 1, false},       -- 环绕:4294967295 比 1 旧
    {500, 500, false},        -- 相等
}

print("测试 is_newer_mod:")
for _, t in ipairs(tests) do
    local a, b, expected = t[1], t[2], t[3]
    local result = is_newer_mod(a, b)
    print(string.format("a=%u, b=%u → %s (期望 %s) %s",
        a, b, tostring(result), tostring(expected),
        (result == expected) and "✓" or "✗"))
end

print("\n测试 is_newer_bit:")
for _, t in ipairs(tests) do
    local a, b, expected = t[1], t[2], t[3]
    local result = is_newer_bit(a, b)
    print(string.format("a=%u, b=%u → %s (期望 %s) %s",
        a, b, tostring(result), tostring(expected),
        (result == expected) and "✓" or "✗"))
end

原理简述

32位无符号序号范围 0~4,294,967,295,当达到最大值后归零。判断新旧的标准:

  • 计算差值 diff = (a - b) mod 2^32,结果落在 [0, 2^32)。
  • 若 diff < 2^31,说明 a 在 b 之后(新);否则 a 在 b 之前(旧)。
  • 若 diff == 0 表示相等。

该算法利用"半个区间"规则,在环形空间内确定前进方向。

相关推荐
企业数字化笔记5 小时前
多租户系统从哪里开始设计?租户身份、数据隔离、权限与套餐的整体方案
java·spring boot·后端·junit
网络毒刘3 天前
端到端:用 Cursor Agent 完成「小功能 + 单测 + PR 描述」并附人工验收清单
单元测试·agent·ai编程·cursor·工具实践
mont evergreen3 天前
RTMP 连接单元测试之旅
单元测试·音视频·源码解读
二喵❥(^_-)3 天前
接口测试流程的三个核心环节
开发语言·lua
我就是不信4 天前
CuTest:轻量级 C 语言单元测试框架实战指南
c语言·单元测试·log4j
众链网络4 天前
大客流票务系统怎么防超卖:库存并发、候补队列与幂等设计的工程取舍
junit·架构
深念Y7 天前
rime-雾凇拼音-配置记录
linux·junit·软件·拼音·kde
虫无涯8 天前
Coverity 如何结合 GJB8114-2013使用?
git·单元测试·嵌入式测试·coverity·静态扫描
小师兄吃牛肉9 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
喜欢的名字被抢了9 天前
09-Redis 进阶原理篇:单线程、多线程、过期、LRU-LFU、Fork 与 Lua
数据库·redis·lua