Swift 5 格式化浮点数:将格式化产生的-0.00转换为无符号0.00
问题原因
NumberFormatter输出-0.00是因为传入的浮点数按指定取整规则截断后得到了负零值(即值介于-1/(10^n)和0之间,n为保留的小数位数),格式化器会默认保留负号输出。你当前代码还存在一处缺失:roundingMode的赋值分支没有写完,会导致取整规则不生效。
实现方案
推荐用结果兜底校验的方式实现,不需要适配不同取整规则、不同地区的小数点格式,兼容性最好,修改成本最低:
- 先补全
roundingMode分支缺失的赋值逻辑 - 拿到格式化结果后,判断结果转换为数值是否等于0,如果是则直接返回格式化后的正零值,彻底规避负零问题
修改后的完整代码如下:
static func formatValue(_ value: Double, currency: Currency? = nil, options: [FormatterOption] = [], locale: Locale = Locale.current) -> String { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.locale = locale let defaultOptions: [FormatterOption] = [.minFractionDigits(2), .maxFractionDigits(currency?.decimals ?? 2), .roundingMode(.down)] for option in defaultOptions + options { switch option { case .minFractionDigits(let minValue): if let decimals = currency?.decimals, minValue > decimals { continue } formatter.minimumFractionDigits = minValue case .maxFractionDigits(let maxValue): if let decimals = currency?.decimals, maxValue > decimals { continue } formatter.maximumFractionDigits = maxValue case .roundingMode(let mode): // 补全原代码缺失的赋值逻辑 formatter.roundingMode = mode } } guard let formattedNumber = formatter.string(from: NSNumber(value: value)) else { // 格式化失败兜底返回0.00 return formatter.string(from: 0.0) ?? "0.00" } // 负零修正:如果格式化结果转数值等于0,统一返回无符号零 if let resultValue = Double(formattedNumber), resultValue == 0 { return formatter.string(from: 0.0) ?? "0.00" } return formattedNumber }
如果你封装的
formatter.format(from:)方法是对string(from:)的二次封装,把上面对应获取格式化字符串的代码替换成你原有的调用即可,负零判断逻辑不需要改动。
测试验证
- 传入值
-0.008,保留2位小数、取整模式为截断场景下,最终返回结果为0.00,符合预期 - 传入值
-0.01,保留2位小数时返回-0.01,不会误改正常负数的格式 - 传入值
0.004,保留2位小数时返回0.00,无多余负号
内容的提问来源于stack exchange,提问作者akitainu22
相关产品推荐
相关产品推荐

