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 表示相等。

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

相关推荐
测试修炼手册21 小时前
[测试技术] TestNG 入门与实战:分组、数据驱动与并行执行
junit·单元测试·log4j
START_GAME1 天前
LuaTools的使用指南
junit
川石课堂软件测试2 天前
安全测试|常见SQL注入攻击方式、实例及预防
服务器·数据库·sql·功能测试·测试工具·安全·单元测试
测试修炼手册2 天前
[测试技术] JUnit 6 入门与实战:断言、参数化与 Mockito
数据库·junit·sqlserver
在水一缸2 天前
深入浅出 Catch2:现代 C++ 测试框架的优雅实践
开发语言·c++·单元测试·log4j·测试框架·catch2
花椒技术3 天前
AI Coding 后半程:6 类 QA Skills 如何接住测试与发布?
单元测试·ai编程·测试
疯狂打码的少年3 天前
【软件工程】软件测试阶段:单元测试与集成测试(高频对比考点)
笔记·单元测试·集成测试·软件工程
●VON3 天前
鸿蒙 PC Markdown 编辑器查找系统:大小写、整词与循环定位
华为·单元测试·编辑器·harmonyos·鸿蒙
川石课堂软件测试4 天前
安全测试|服务器安全加固方法
服务器·功能测试·测试工具·jmeter·mysql·web安全·单元测试
测试修炼手册5 天前
[测试技术] GoogleTest 入门与实战:单元测试、参数化与 Mock
单元测试