Lua 浮点数比较

更简单
lua 复制代码
-- 默认容差为 1e-12(可根据实际精度调整)
function float_eq(a, b, epsilon)
    epsilon = epsilon or 1e-12
    return math.abs(a - b) <= epsilon
end

-- 容差比较基础函数
function nearly_equal(a, b, eps)
    eps = eps or 1e-12
    return math.abs(a - b) <= eps
end

-- a < b
function float_lt(a, b, eps)
    return a + (eps or 1e-12) < b
end

-- a <= b
function float_le(a, b, eps)
    return a <= b + (eps or 1e-12)
end

-- a > b
function float_gt(a, b, eps)
    return a > b + (eps or 1e-12)
end

-- a >= b
function float_ge(a, b, eps)
    return a + (eps or 1e-12) >= b
end

更安全

lua 复制代码
-- ============================================================================
-- 浮点数比较
-- ============================================================================

local math_abs = math.abs
local math_max = math.max

-- 默认绝对容差(适用于接近零的值)
local DEFAULT_EPS_ABS = 1e-12
-- 默认相对容差(适用于大数值)
local DEFAULT_EPS_REL = 1e-12

-- 判断一个数是否为 NaN(Lua 中直接比较 x ~= x 即可)
local function is_nan(x)
    return x ~= x
end

-- 判断一个数是否为有限数(非 NaN 且非无穷)
local function is_finite(x)
    if x ~= x then return false end          -- NaN
    if x == math.huge or x == -math.huge then return false end
    return true
end

-- ============================================================================
-- 两个浮点数是否近似相等(考虑绝对误差和相对误差)
-- @param a 第一个数
-- @param b 第二个数
-- @param eps_abs 绝对容差(默认 1e-12)
-- @param eps_rel 相对容差(默认 1e-12)
-- @return boolean true 表示相等(在容差范围内)
-- ============================================================================
function float_eq(a, b, eps_abs, eps_rel)
    eps_abs = eps_abs or DEFAULT_EPS_ABS
    eps_rel = eps_rel or DEFAULT_EPS_REL

    -- 处理 NaN:NaN 与任何值(包括自身)都不相等
    if is_nan(a) or is_nan(b) then
        return false
    end

    -- 处理无穷大:符号相同的无穷大视为相等
    if a == math.huge and b == math.huge then return true end
    if a == -math.huge and b == -math.huge then return true end

    -- 对于非常大的数,使用相对误差;对于接近零的数,使用绝对误差
    local diff = math_abs(a - b)
    if diff <= eps_abs then
        return true
    end

    -- 相对误差(防止除以零,取分母绝对值较大者)
    local max_val = math_max(math_abs(a), math_abs(b))
    if max_val > 0 then
        local rel_err = diff / max_val
        if rel_err <= eps_rel then
            return true
        end
    end

    return false
end

-- ============================================================================
-- 比较 a < b (严格小于,考虑容差)
-- 规则:当 a 明显小于 b 时(差值超过容差)返回 true
-- ============================================================================
function float_lt(a, b, eps_abs, eps_rel)
    eps_abs = eps_abs or DEFAULT_EPS_ABS
    eps_rel = eps_rel or DEFAULT_EPS_REL

    -- NaN 无法比较,返回 false
    if is_nan(a) or is_nan(b) then
        return false
    end

    -- 无穷处理:任何有限数 < +inf;-inf < 任何有限数
    if a == -math.huge and b ~= -math.huge then return true end
    if b == math.huge and a ~= math.huge then return true end
    if a == math.huge or b == -math.huge then return false end

    -- 如果 a 和 b 近似相等,则不认为 a < b
    if float_eq(a, b, eps_abs, eps_rel) then
        return false
    end

    -- 否则直接比较数值
    return a < b
end

-- ============================================================================
-- 比较 a <= b (小于等于,考虑容差)
-- ============================================================================
function float_le(a, b, eps_abs, eps_rel)
    return float_lt(a, b, eps_abs, eps_rel) or float_eq(a, b, eps_abs, eps_rel)
end

-- ============================================================================
-- 比较 a > b (严格大于)
-- ============================================================================
function float_gt(a, b, eps_abs, eps_rel)
    return float_lt(b, a, eps_abs, eps_rel)
end

-- ============================================================================
-- 比较 a >= b
-- ============================================================================
function float_ge(a, b, eps_abs, eps_rel)
    return float_gt(a, b, eps_abs, eps_rel) or float_eq(a, b, eps_abs, eps_rel)
end

-- ============================================================================
-- 工具:判断一个数是否为有效的非零浮点数(结合之前的转换函数)
-- 假设 to_float 已经定义(返回 ok, value)
-- ============================================================================
function is_valid_nonzero_float(input)
    local ok, val = to_float(input)   -- 请确保 to_float 已实现
    return ok
end

-- ============================================================================
-- 测试示例(包含边界情况)
-- ============================================================================
local function run_tests()
    print("========== 浮点数比较测试 ==========")

    -- 基本相等(含精度误差)
    print(float_eq(0.1 + 0.2, 0.3))              --> true
    print(float_eq(1e-100, 0, 1e-99))            --> true (绝对容差)
    print(float_eq(1e100, 1e100 + 1e85, nil, 1e-12)) --> true (相对容差)

    -- 不等
    print(float_eq(0.1, 0.2))                    --> false

    -- 无穷大比较
    print(float_eq(math.huge, math.huge))        --> true
    print(float_eq(math.huge, -math.huge))       --> false
    print(float_lt(1e200, math.huge))            --> true
    print(float_lt(-math.huge, -1e200))          --> true

    -- NaN 比较
    local nan = 0/0   -- 在 Lua 中需要某些环境,通常直接构造:tonumber("nan") 或 0*math.huge
    -- 由于 Lua 默认不支持 NaN 字面量,用以下方式模拟(如果有)
    if is_nan(0/0) then
        print(float_eq(nan, nan))                --> false
        print(float_lt(nan, 1))                  --> false
    end

    -- 大小比较
    print(float_lt(0.1, 0.2))                    --> true
    print(float_lt(0.2, 0.1))                    --> false
    print(float_le(0.1, 0.1 + 1e-15))            --> true(容差内视为相等)
    print(float_gt(0.2, 0.1))                    --> true
    print(float_ge(0.1, 0.1 - 1e-15))            --> true
end

-- run_tests()  -- 取消注释以运行测试
相关推荐
千里码aicood21 小时前
基于Python的电商数据采集系统(大数据+爬虫)
开发语言·python
陈皮波比茶21 小时前
Python项目实战-网络机器人(爬虫)
开发语言·网络·爬虫·python·机器人
法哥20121 天前
用 C++ 控制 CMW100,到底在干什么?
开发语言·c++
QH139292318801 天前
NVIDIA H200 H300服务器
运维·服务器·开发语言·网络·信息与通信
OPEN-F1 天前
Python进阶教程:单元测试与代码质量
开发语言·python·单元测试
阿里嘎多学长1 天前
2026-08-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
其实防守也摸鱼1 天前
Codex破局:前端组件秒级生成的技术文章大纲
开发语言·前端·人工智能·学习·安全·web安全
Logintern091 天前
装饰器和洋葱模式的区分
开发语言·python·架构
冻柠檬飞冰走茶1 天前
《数据结构实验指导-C++语言版》 在顺序表 list 中查找元素 x
开发语言·数据结构·c++·算法·list
Brilliantwxx1 天前
【C++】 高阶数据结构图(1)并查集
开发语言·数据结构·c++