NumberFormatter返回错误的数字



我测试NumberFormatter从priceWithCurrency获取数字。

如果价格大于$70 NumberFormatter转换错误的数字。

lazy var currencyFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencyCode = "USD"
return formatter
}()

let price = "$71.9"
currencyFormatter.number(price)
//71.90000000000001

如果您对71.8做同样的事情,它将工作。这是因为71.9不能精确地用浮点数表示(由于位的有限性)

使用整数(以分为单位的价格)或十进制数是正确处理价格的唯一问题。检查DecimalNSDecimalNumber类,看看您可以使用它做什么。

特别建议你做一些价格计算,(如果你和两个朋友用现金支付10美元,两个会支付3.33,一个会支付3.34——所以根据你的情况,除以3可能不够)

let number = currencyFormatter.number(from: price) ?? NSNumber(value: 0)
var value =  number.decimalValue
var roundedValue: Decimal = 0
// Right way: ( choose your precisions - 3 decimals here):
NSDecimalRound(&roundedValue, &value, 3, .bankers)
print(number)
print(value)
print(roundedValue)
71.90000000000001
71.90000000000001
71.9

如果你只需要记录你的价格,只需使用Int(price*100)/100它会完成工作的

如果你需要更多…祝你好运:)

编辑

在@Nicholas Rees的精彩评论之后,我添加了这个变体:

currencyFormatter.generatesDecimalNumbers = true
let number = (currencyFormatter.number(from: price) as? NSDecimalNumber) ?? NSDecimalNumber(value: 0)
var value =  number.decimalValue
var roundedValue: Decimal = 0
// Right way: ( choose your precisions - 3 decimals here):
NSDecimalRound(&roundedValue, &value, 3, .bankers)
print(number)
print(value)
print(roundedValue)

在那里,结果在相同时记录,但我认为'值'的内部格式是正确的

另一种方法是删除货币并从string:

创建十进制。
print(Decimal(string: "71.9") ?? 0)
71.9

最新更新