You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中1.005四舍五入至两位小数结果异常问题及解决方法

解决Swift中1.005保留两位小数时round方法返回1.0而非1.01的问题

嘿,这个问题其实是浮点数精度误差搞的鬼!你遇到的情况特别典型,咱们一步步拆解来看:

为什么会出现这个问题?

Double类型是基于二进制的浮点数,它没办法精确表示所有十进制小数。比如你用到的1.005,在二进制里是一个无限循环的近似值,实际存储的数值其实是略小于1.005的(大概是1.0049999999999998...)。当你执行value * 100时,这个近似值乘以100后就变成了100.49999999999998...,再用round()函数处理,自然就会向下取整到100,最后除以100.0就得到了1.0,而非预期的1.01。

至于测试代码里其他数字(比如2.005)能得到正确结果,是因为它们的二进制近似值刚好略大于实际的十进制数,乘以100后会超过200.5,round()就会向上取整。

靠谱的解决方案

1. 使用Decimal类型处理精确十进制计算

Decimal是专门为十进制小数设计的类型,能从根源上避免二进制浮点数的精度问题。示例代码:

for i in 1..<11 {
    let value = Decimal(i) + Decimal(string: "0.005")!
    let roundedValue = (value * 100).rounded() / 100
    print("\(value) -> \(roundedValue)")
}

运行这段代码,所有数值都会正确保留两位小数,1.005会得到1.01。

2. 使用NumberFormatter格式化输出(适合UI展示)

如果你的需求只是把数值格式化为字符串展示给用户,直接用NumberFormatter更简单,它内部会自动处理精度问题:

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
formatter.roundingMode = .halfUp

for i in 1..<11 {
    let value = Double(i) + 0.005
    if let formattedString = formatter.string(from: NSNumber(value: value)) {
        print("\(value) -> \(formattedString)")
    }
}

这个方法输出的字符串会是你预期的"1.01"、"2.01"等格式,非常适合界面展示场景。

3. 手动添加极小偏移量(不推荐,慎用)

如果不想切换类型,也可以尝试给原数值加一个极小的偏移量(比如1e-8)来抵消精度误差:

for i in 1..<11 {
    let value = Double(i) + 0.005
    let offsetValue = value + 1e-8
    let roundedValue = round(offsetValue * 100) / 100.0
    print("\(value) -> \(roundedValue)")
}

不过这个方法不够可靠,不同数值可能需要不同的偏移量,极端场景下可能会引入新的错误,所以只建议临时应急使用。

总结

优先推荐用Decimal做精确的十进制计算,或者用NumberFormatter做格式化展示,这两种方法都能彻底解决浮点数精度导致的四舍五入错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:29:05