swift - 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”。我的理解有误吗?
解决方案
试试下面的代码:
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
如果要转换Double
为Decimal
精确表示print
ed 值,则可能需要更多代码。
推荐阅读
- ruby-on-rails - 通过 webpack 将 CKEditor 4 与 Rails 6 集成
- kubernetes - 将离子应用程序部署到 EKS 部署后不加载网站
- javascript - 从 Firestore 获取值时 useState 不更新
- java - 在 CircleCI,当使用多个图像时无法访问 gradle
- r - GGPLOT 标签设计(粗体、间隙)
- hibernate - 如何正确编写查询,以免出现意外的令牌异常?
- flutter - Dart/Flutter - 如何获得自 epoch 以来的第二个:Twitter API 错误代码 135(时间戳超出范围)
- python - mkdir /path: 运行 geth 时出现只读文件系统问题
- r - R:关于使用 lapply() 函数而不是 for 循环的问题
- javascript - Matter.js 通过鼠标拖动选择多个实体