CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

Lua数字转中文:进位读法的查表拼接

2026-10-02 03:32 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【语法算法】

先抛一个坑:数字能转中文大写吗?一百零二转"一百零二"看着简单,中间那个零才是难题——一千零一、一万零二百、一百二十,零什么时候补、补几个,进位读法的账比看上去密。数字转中文的写法就是一本进位读法的账:逐位查表、进位拼接、零位补读,三步走完,阿拉伯数字就念出了中文的调。这篇把整套写法拆开:配置表、数位查表、零位补读、进位拼接、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:进位读法的查表拼接

演示场上下两格:上格是阿拉伯数字,下格是它的中文读法。点「随机数」:一个五位数以内的数落下——上格显示数值,下格当场拼出中文读法,一零二四念"一千零二十四",中间的零一个不少。点「加一」:数字逐个往上加——每加到进位的边界,中文读法当场换调。点「整数」:跳到两万零一——万位和个位之间的三个零只补读一个零,这是进位读法最讲究的一处。演示里试两笔账:零位补读的数目和数字里零的个数——零再多也只补读一个,中文的规矩就是这么省。数字转中文教的是查表:数位查表拼接,零位补读兜底——两张小表加一条补读的规矩,撑起中文数数的一片天。

mermaid
flowchart TD
A[数字逐位拆开] --> B[每位查数字表]
B --> C{这一位是零}
C -- 是 --> D[已拼了零就跳过 未拼补读零]
C -- 否 --> E[查数位表拼接进位单位]
D --> F[数字右移一位]
E --> F
F --> G{还有位吗}
G -- 是 --> B
G -- 否 --> H[输出中文读法]
demo
 fx-numtocn

二、底层原理:一张数位表加一次零位补读

模块的机关是一对搭档。数位查表:数字逐位拆开逐位查表——数字表十个字、进位表五个字,两张小表撑起五位数以内的全部读法。零位补读:连续的零只在恰当的位置补读一个——零是读法的润滑剂,多了啰嗦少了歧义,补读的位置就是中文数数的规矩。和逐字硬翻的分野在"零位补读懂省略":逐字硬翻会把一千零二十四翻成一千零二零四,账面没错读法全错;零位补读是懂中文数数的人在翻译,零补在哪、补不补,全按念的规矩来——规矩是人念出来的,写代码之前先自己念三遍。

零位补读为什么只在未拼时补?连着的零补一个就够——一千零零一的读法是"一千零一"不是"一千零零一",已拼了零就跳过,这条是中文读法最省的规矩,也是查表时最容易写错的一处。

三、核心代码:完整模块(上·骨架)

lua
-- @file NumToCN.lua
-- 数字转中文 —— 进位读法的查表拼接

local NumToCN = {}

local CONST = {
    DIGITS        = { "零", "一", "二", "三", "四",
                      "五", "六", "七", "八", "九" },
    UNITS         = { "", "十", "百", "千", "万" },
    MAX_DIGITS    = 5,

    AUTOINC_BASE  = 1163000,
}

local _num       = 0
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "NTC",
        CONST.AUTOINC_BASE + _autoInc)
end

local function ShowTip(msg)
    if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end

function NumToCN.SetNum(n)
    _num = math.floor(math.max(0, n))
end

function NumToCN.Num()
    return _num
end

四、核心代码:完整模块(下·零位补读与进位拼接)

lua
-- 逐位查表拼接:零位补读的完整账
function NumToCN.Convert()
    local n = _num
    if n == 0 then return CONST.DIGITS[1] end
    local out = ""
    local unit = 0
    local zeroPending = false
    while n > 0 do
        local d = n % 10
        if d == 0 then
            if not zeroPending and out ~= "" then
                zeroPending = true
            end
        else
            if zeroPending then
                out = CONST.DIGITS[1] .. out
                zeroPending = false
            end
            out = CONST.DIGITS[d] .. CONST.UNITS[unit + 1] .. out
        end
        n = math.floor(n / 10)
        unit = unit + 1
    end
    return out
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("随机数", function()
        NumToCN.SetNum(math.random(0, 99999))
        ShowTip("随机数:" .. NumToCN.Num()
            .. " 读作 " .. NumToCN.Convert())
    end)
    ShowTip("技能已加载: 数字转中文 (调试按钮触发)")
end, 1.0)

function NumToCN.Unload()
    _num = 0
end

return NumToCN

五、机制问答

问:一万零一中间的三个零怎么只补读一个?
答:补读一条——零位记号挂着就不再重复补,三个零共享一个补读位,念出来才是一千零一不是一千零零零一。

问:超过五位数还能转吗?
答:账本只到万——十万以上要再添"十万""百万"的进位表,表不够长就先不接单,账本的诚实是查表法的本分。

问:负数能转吗?
答:能——前置一个"负"字再走正数的账,读法的主体不变,负号是门口的一块牌子——进门前先看牌子,牌子后面的账照旧走。

问:零位补读和英文读法一样吗?
答:不一样——英文的零不补读,一千零一和一千一英文读着一样,中文的零必须补,两套规矩别互相套。

问:进位单位为什么从空串开始?
答:个位没有单位——单位表第一格是空串,个位的数字光着拼就行,从十位才开始挂单位。

六、调参与实战怎么用

第四笔是零位记号的规矩:未拼才补、拼过即跳是读法的灵魂——每零必补的版本啰嗦,全不补的版本歧义,这一处是数字转中文全部的难度所在。第三笔是进位表的长度:五格进位表管五位数——表的长短就是账本的容量,容量写死在配置里,超额直接拒单别硬翻——账本的容量写在那儿,翻不动的账硬翻只会错得更体面。第二笔是取整的时机:逐位取余前先取整降位——忘了取整的版本同一位反复读,账越读越长。第一笔是零的特判:零数字单独走一格出口——整本账只有零最难念,零的读法是唯一的特例也是唯一的门面。常见坑三个:连续零重复补读;进位单位错位一格;超大数静默截断没有拒单提示。

实战里数字转中文是"读法类"玩法的通用件:翻牌报数、任务口播、拍卖唱价,全是"逐位查表补零拼接"的同一副骨架。组里的约定是:凡是念给玩家听的数字一律转中文读法——阿拉伯数字是看的,中文数字是念的,两套各有各的岗位。这篇的模块照抄能跑,改的就是两张表。

写完留一句给做读法系的同学:数字转中文卖的是"零补在哪"——那一个见缝插针的零字和逐位查表的两张小表,是把阿拉伯数字念出中文腔的一本进位账。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

Lua自动炮台:架一个自动索敌开火

【语法算法】 上一版的炮台索敌逻辑有个隐蔽报错:炮台永远打同一个怪——即使那只怪已经死了,索敌的游标也不挪窝。追到底索敌的游…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua元素转换:火伤转冰伤附带减速

【语法算法】 先抛一个坑:打不完的火系怪怎么办?火抗怪火打不动,换冰系技能要切装备要换面板——切完黄花菜都凉了。元素转换的答…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua连锁引燃:一个着火引燃下一个

【语法算法】 上个月的事故复盘会上有个数字被念了三遍:四成——策划写的是"同伴陪疼四成",代码落下去成了"陪疼四十点",两只…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua弹射地垫:踩上去弹飞到空中

【语法算法】 单行代码拆解:弹射初速=-420——弹射的全部动力就这一行的负初速。负号朝上、四百二十是弹射的初速大小——踩上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua时间减缓:流速减半的局部时差

【语法算法】 上一版的减速类模块全按"乘以零点五"来写,帧率无关的版本照搬了这套写法——结果高帧率机上减速效果好,低帧率机上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua引力球:丢出去把怪吸过来

【语法算法】 先抛一个坑:怎么把散在四处的怪聚到一起打?逐个拉是笨办法,一个范围技又只能打一片——引力球的答案是一个会动的吸…

2026-10-02 04:50 996 技术组