为什么你的Lua小数截取总出错?深度解析浮点型精度陷阱与解决方案
在游戏开发、金融计算等对数值精度要求严格的领域,Lua开发者经常遇到一个令人头疼的问题:看似简单的截取小数点后两位操作,却总会出现意料之外的结果。比如将1.9999截取为1.99的需求,使用常规方法却得到了2.00。这背后隐藏着浮点数存储原理、Lua特有运算规则等一系列技术陷阱。
1. 浮点数的本质与Lua的实现
Lua中的number类型默认采用IEEE 754双精度浮点格式存储,这种设计虽然能表示极大范围的数值,但在处理小数时存在固有缺陷。浮点数在内存中是以二进制分数形式存储的,很多十进制小数无法精确表示为二进制分数,这就导致了著名的"0.1 + 0.2 ≠ 0.3"问题。
浮点数精度关键特性:
- 有效数字约16-17位十进制数
- 绝对值范围约±5.0×10⁻³²⁴到±1.7×10³⁰⁸
- 不是所有十进制小数都能精确表示
-- 典型浮点精度问题示例
print(0.1 + 0.2) -- 输出0.30000000000000004而非0.3
2. 常见错误方案剖析
2.1 string.format的四舍六入陷阱
许多开发者首先想到的是使用string.format进行格式化输出,但这存在严重问题:
function badFormat(val)
return tonumber(string.format("%.2f", val))
end
print(badFormat(1.9999)) -- 输出2.0而非期望的1.99
四舍六入五成双规则:
- 被修约数字小于5时舍去
- 被修约数字大于5时进位
- 等于5时看前一位数字:奇数则进位,偶数则舍去<

141

被折叠的 条评论
为什么被折叠?



