首页 > 解决方案 > NumberFormatter 奇怪的行为

问题描述

我在 Swift 的 NumberFormatter 中发现了一个奇怪的行为。

func testNumberFormat() {
    let numberFormat = { (number: NSNumber) -> (String?) in
        let formatter: NumberFormatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.maximumFractionDigits = 2
        formatter.minimumFractionDigits = 2
        formatter.roundingMode = .halfUp

        return formatter.string(from: number)
    }

    XCTAssertEqual(numberFormat(Decimal(0.004) as NSNumber)!, "0.00") // OK
    XCTAssertEqual(numberFormat(Decimal(0.005) as NSNumber)!, "0.01") // OK
    XCTAssertEqual(numberFormat(Decimal(10000.004) as NSNumber)!, "10,000.00") // OK
    XCTAssertEqual(numberFormat(Decimal(10000.005) as NSNumber)!, "10,000.01") // NG!
    XCTAssertEqual(numberFormat(Decimal(10000.014) as NSNumber)!, "10,000.01") // OK
    XCTAssertEqual(numberFormat(Decimal(10000.015) as NSNumber)!, "10,000.02") // OK
}

以下测试失败。

XCTAssertEqual(numberFormat(Decimal(10000.005) as NSNumber)!, "10,000.01") 

我期望“10,000, 01”,但返回“10,000, 00”。我的理解有误吗?

标签: swift

解决方案


试试下面的代码:

print(Decimal(10000.005)) //->10000.004999999997952

您知道10000.004999999997952将被格式化为10,000.00与您的numberFormat.

二进制浮点Double不能表示 的精确值10000.005,因此结果Decimal.init(_: Double)难以预测。

如果要在 中保存精确的十进制表示Decimal,则应Decimal(string:)改用。

print(Decimal(string: "10000.005")!) //->10000.005
print(numberFormat(Decimal(string: "10000.005")! as NSNumber)!) //->10,000.01

如果要转换DoubleDecimal精确表示printed 值,则可能需要更多代码。


推荐阅读