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

iOS自定义金额输入控件数字精度异常:88.99转成88.98999999999999求助

解决金额输入控件中NumberFormatter导致的浮点数精度问题

这个问题其实是二进制浮点数的精度局限性在搞鬼,加上你当前用的NumberFormatter默认会把字符串转成Double类型,而Double无法精确表示像0.99这样的十进制小数,才会出现这种奇怪的近似值。

问题根源拆解

  • 当你调用number(from: "88.99")时,NumberFormatter默认返回的是Double类型的NSNumber。而十进制的88.99转换成二进制浮点数时,会变成一个无限循环的近似值——也就是你看到的88.98999999999999,这是浮点数的天生缺陷。
  • 你设置的minimumFractionDigits和maximumFractionDigits是用来控制输出字符串的格式的,只会影响最终显示的小数位数,但不会改变底层数值的存储精度。所以这些设置无法解决浮点数本身的近似问题。

解决方案

方案1:让NumberFormatter返回Decimal类型(强烈推荐)

Decimal(对应OC的NSDecimalNumber)是专门为精确十进制计算设计的类型,不会出现二进制浮点数的精度丢失问题。只需要给你的Formatter添加一行配置,让它返回Decimal类型的数值:

extension NumberFormatter {
    static public func defaultCurrencyFormatter() -> NumberFormatter {
        let formatter = NumberFormatter()
        formatter.usesGroupingSeparator = true
        formatter.numberStyle = .currency
        formatter.currencySymbol = ""
        formatter.minimumFractionDigits = 1
        formatter.maximumFractionDigits = 2
        formatter.currencyGroupingSeparator = ","
        formatter.currencyDecimalSeparator = "."
        // 关键配置:让Formatter生成Decimal类型的数值
        formatter.generatesDecimalNumbers = true
        return formatter
    }
}

// 测试代码
let formatter = NumberFormatter.defaultCurrencyFormatter()
if let decimalNumber = formatter.number(from: "88.99") as? NSDecimalNumber {
    print(decimalNumber.stringValue) // 输出 "88.99",完美匹配输入值
}

方案2:用Formatter重新格式化数值(临时 workaround)

如果因为某些限制不能使用Decimal,可以在拿到Double值后,不要直接取stringValue,而是用同一个Formatter把数值重新转成格式化后的字符串,这样就能得到正确的两位小数结果:

let formatter = NumberFormatter.defaultCurrencyFormatter()
if let number = formatter.number(from: "88.99") {
    let correctedString = formatter.string(from: number)
    print(correctedString) // 输出 "88.99"
}

针对你的自定义控件的优化建议

  • 存储用户输入的金额时,用Decimal类型代替Double,避免精度丢失;
  • 从编辑模式切换到显示模式时,用Formatter把Decimal转成带格式的字符串(比如"$ 88.99")给UILabel;
  • 再次进入编辑模式时,直接使用存储的Decimal的stringValue(或者用Formatter生成不带格式的纯数字字符串)填充UITextField,确保编辑的数值和用户之前输入的完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:54:35