NumberFormatter return 错误的数字

NumberFormatter return the wrong number

我测试 NumberFormatter 以从 priceWithCurrency 获取数字。

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

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


let price = ".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)

那里,登录时的结果相同,但我想 'value' 的内部格式是正确的

另一种方法是从字符串中删除货币并创建小数:

print(Decimal(string: "71.9") ?? 0)

71.9