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

Swift中NumberFormatter为何将19,999,999,999,999,999格式化为20,000,000,000,000,000?

Swift中NumberFormatter格式化大整数出现精度丢失的原因及解决方法

问题原因

这个问题的核心是Double精度限制导致的近似误差:

  • Swift的64位Int能容纳的范围(-9223372036854775808 到 9223372036854775807)远大于Double的精确整数范围,Double仅能精确表示2^53以内的整数(约9007199254740992)。
  • 当你把超过这个范围的Int转换成NSNumber后,NumberFormatter内部会默认以Double类型解析数值,而Double无法精确存储19999999999999999这类大整数,会自动近似为最接近的可表示值20000000000000000,最终导致格式化结果不符合预期。

解决方案

有两种可靠的解决方式,任选其一即可:

方案一:用NSDecimalNumber避免Double转换

修改格式化函数,使用NSDecimalNumber包装整数,让NumberFormatter以高精度小数模式处理,彻底规避精度丢失:

import Foundation

func format(_ num: Int) -> String {
    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.groupingSeparator = ","
    formatter.groupingSize = 3
    // 用NSDecimalNumber包装整数,确保高精度处理
    let decimalNum = NSDecimalNumber(value: num)
    return formatter.string(from: decimalNum) ?? String(num)
}

方案二:字符串手动添加分隔符

完全绕过NumberFormatter,直接对整数的字符串形式进行处理,手动插入逗号分隔符:

import Foundation

func format(_ num: Int) -> String {
    let numStr = String(num)
    var formatted = ""
    let reversedStr = numStr.reversed()
    
    for (index, char) in reversedStr.enumerated() {
        if index != 0 && index % 3 == 0 {
            formatted += ","
        }
        formatted.append(char)
    }
    
    return String(formatted.reversed())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:40:39