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

Ubuntu 22.04下NumberFormatter格式化Float小数位数异常求助

Float值在Linux下NumberFormatter格式化异常的解决办法

需要将数值始终保留逗号后2位小数,但部分Float值在Linux(Ubuntu 22.04)环境下无法通过NumberFormatter正确格式化,macOS 14.7下运行正常。

代码示例

import Foundation
let floatNumber: Float = 17889.055
let roundedNumber: Float = (floatNumber * 100).rounded() / 100
let formatter: NumberFormatter = NumberFormatter()
formatter.locale = Locale(identifier: "de_DE")
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
formatter.groupingSeparator = "."
formatter.decimalSeparator = ","

print(formatter.string(from: NSNumber(value: floatNumber)) ?? String(format: "%.2f", floatNumber)) 
print(formatter.string(from: NSNumber(value: roundedNumber)) ?? String(format: "%.2f", roundedNumber)) 

实际输出(Linux)

swift test.swift 
17.889,055
17.889,061

预期输出

swift test.swift 
17.889,06
17.889,06

macOS下输出

17.889,05
17.889,06

解决办法

方案1:改用Double类型

Float是单精度浮点型,无法精确存储17889.055这类十进制小数,实际存储值存在微小误差。Linux下Foundation对该误差的处理逻辑和macOS不同,导致格式化结果异常。改用双精度的Double能大幅降低精度偏差:

import Foundation
let doubleNumber: Double = 17889.055
let roundedDouble: Double = (doubleNumber * 100).rounded() / 100
let formatter: NumberFormatter = NumberFormatter()
formatter.locale = Locale(identifier: "de_DE")
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
formatter.groupingSeparator = "."
formatter.decimalSeparator = ","

print(formatter.string(from: NSNumber(value: doubleNumber)) ?? String(format: "%.2f", doubleNumber)) 
print(formatter.string(from: NSNumber(value: roundedDouble)) ?? String(format: "%.2f", roundedDouble)) 

方案2:使用Decimal类型精确处理

Decimal专为十进制精确运算设计,完全避免浮点精度丢失问题,是处理货币、精确小数场景的最优选择:

import Foundation
let decimalNumber = Decimal(string: "17889.055")!
let roundedDecimal = decimalNumber.rounding(accordingTo: .init(scale: 2, roundingMode: .plain))
let formatter: NumberFormatter = NumberFormatter()
formatter.locale = Locale(identifier: "de_DE")
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
formatter.groupingSeparator = "."
formatter.decimalSeparator = ","

print(formatter.string(from: roundedDecimal as NSNumber) ?? "\(roundedDecimal)")

原因总结

  • Float的单精度存储特性导致无法精确表示部分十进制小数,存储值存在误差;
  • Linux与macOS的Foundation框架对浮点误差的格式化处理逻辑存在差异,引发输出异常;
  • Double提升精度减少误差,Decimal则从根源上解决精度问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:24:50