NumberFormatter 错误结果为 0.9972

NumberFormatter wrong result for 0.9972

我有一个双:

let value = 0.99720317490866084

以及双扩展功能:

extension Double {
    func stringWithFixedFractionDigits(min: Int, max: Int) -> String {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = min
        formatter.maximumFractionDigits = max
        formatter.minimumIntegerDigits = 1
        let numberObject = NSNumber(value: self)
        return formatter.string(from: numberObject) ?? "\(self)"
    }
}

如果我使用:

value.stringWithFixedFractionDigits(min: 2, max: 2)

我得到 1.00 但我想得到 0.99

我能改变什么?

您只需将 NumberFormatter 舍入模式 属性 设置为 .down:

formatter.roundingMode = .down

请注意,您不需要创建新的 NSNumber 对象,您可以安全地将 Double 转换为 NSNumber 或使用 string(for: Any) 方法。作为替代方案,您可以扩展协议 FloatingPoint 以使其适用于所有 Float 类型:

extension Formatter {
    static let number = NumberFormatter()
}
extension FloatingPoint {
    func formattedWithFractionDigits(minimum: Int = 2, maximum: Int = 2, minimumIntegerDigits: Int = 1, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
        Formatter.number.roundingMode = roundingMode
        Formatter.number.minimumFractionDigits = minimum
        Formatter.number.maximumFractionDigits = maximum
        Formatter.number.minimumIntegerDigits = minimumIntegerDigits
        return Formatter.number.string(for: self) ?? ""
    }
}


0.9972031749.formattedWithFractionDigits()                                              // 1.00
0.9972031749.formattedWithFractionDigits(roundingMode: .down)                           // "0.99"
0.9972031749.formattedWithFractionDigits(minimumIntegerDigits: 0, roundingMode: .down)  // ".99"