You need to enable JavaScript to run this app. Lua中如何在不改变整数值的前提下去除小数尾缀.0
优惠活动
大模型
产品
解决方案
定价
更多

Lua中如何在不改变整数值的前提下去除小数尾缀.0

问题根因

Lua 中数值运算默认会将整数运算结果转为浮点数类型,直接调用tostring()处理浮点数类型的整数值时,就会自动追加.0后缀。你使用math.floor/math.ceil会修改原值的本质原因是运算过程中可能出现的浮点数精度误差:比如理论上应该得到114的运算,实际运行时可能得到113.9999999999999或者114.0000000000001,直接取整就会出现偏差。

解决方案

你可以先对运算后的值做整数判定,再选择对应的转字符串方式,这里提供两个可行方案:

方案1:精度修正后判定转整数(推荐)

先给运算结果加一个极小的容错偏移量(比如1e-6)抵消浮点数精度误差,再判断是否为整数,是就转整数类型再转字符串,否则保留原有小数:

-- 新增通用的数值转字符串工具函数
local function num2str(num)
    -- 极小偏移量修正浮点数精度误差
    local epsilon = 1e-6
    local rounded = math.floor(num + epsilon)
    if math.abs(num - rounded) < epsilon then
        -- 确认是整数,转整数后再转字符串
        return tostring(math.tointeger(rounded))
    end
    -- 非整数保留原有格式
    return tostring(num)
end

如果使用低于5.3的Lua版本,把math.tointeger(rounded)替换为string.format("%d", rounded)即可。

之后把你customEnc、customDec两个函数里所有tostring(newVar)的调用,全部替换成num2str(newVar)即可。

方案2:字符串替换处理(快速兼容)

如果你的业务场景不会出现非整数的运算结果,也可以在转字符串后直接替换掉结尾的.0后缀,无需修改逻辑:

-- 直接替换原有tostring(newVar)即可
tostring(newVar):gsub("%.0$", "")
修正后的代码示例
local OVal = math.random(1, 999)
local SVal = math.random(1, 999)
local TVal = math.random(1, 999)

local function num2str(num)
    local epsilon = 1e-6
    local rounded = math.floor(num + epsilon)
    if math.abs(num - rounded) < epsilon then
        return tostring(math.tointeger(rounded))
    end
    return tostring(num)
end

local function customEnc(STR)
    local currentVar = ""
    local strings = {}
    STR:gsub(".", function(c)
        if c == [[\]] then
            local newVar = tonumber(currentVar)
            if newVar ~= nil then
                newVar = newVar * OVal / SVal
                table.insert(strings, num2str(newVar))
            end
            currentVar = ""
        else
            currentVar = currentVar .. c
        end
    end)
    local newString = ""
    for i,v in pairs(strings) do
        newString = newString .. [[\]] .. v
    end
    newString = newString .. [[\]]
    return newString
end

local function customDec(STR)
    local currentVar = ""
    local strings = {}
    STR:gsub(".", function(c)
        if c == [[\]] then
            local newVar = tonumber(currentVar)
            if newVar ~= nil then
                newVar = newVar / OVal * SVal
                table.insert(strings, num2str(newVar))
            end
            currentVar = ""
        else
            currentVar = currentVar .. c
        end
    end)
    local newString = ""
    for i,v in pairs(strings) do
        newString = newString .. [[\]] .. v
    end
    newString = newString .. [[\]]
    return newString
end

内容的提问来源于stack exchange,提问作者Joakim Hjalmarsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 13:42:01