为 NumberFormatter 生成DecimalNumbers 不起作用

Ash*_*nic 5 numbers decimal swift

我的功能是将字符串转换为十进制

func getDecimalFromString(_ strValue: String) -> NSDecimalNumber {
    let formatter = NumberFormatter()
    formatter.maximumFractionDigits = 1
    formatter.generatesDecimalNumbers = true
    return formatter.number(from: strValue) as? NSDecimalNumber ?? 0
}
Run Code Online (Sandbox Code Playgroud)

但它没有按预期工作。有时它会像

Optional(8.300000000000001)
Optional(8.199999999999999)
Run Code Online (Sandbox Code Playgroud)

而不是 8.3 或 8.2。在字符串中,我有像“8.3”或“8.2”这样的值,但转换后的十进制不符合我的要求。我犯错的任何建议?

Mar*_*n R 7

设置generatesDecimalNumberstrue并不像人们预期的那样工作。返回的值是一个实例NSDecimalNumber(它可以精确地表示值 8.3),但显然格式化程序首先将字符串转换为二进制浮点数(并且不能精确地表示 8.3)。因此返回的十进制值只是近似正确。

这也被报告为一个错误:

另请注意(与文档相反),该maximumFractionDigits属性在将字符串解析为数字时无效。

有一个简单的解决方案:使用

NSDecimalNumber(string: strValue) // or
NSDecimalNumber(string: strValue, locale: Locale.current)
Run Code Online (Sandbox Code Playgroud)

相反,取决于字符串是否已本地化。

或者使用 Swift 3Decimal类型:

Decimal(string: strValue) // or
Decimal(string: strValue, locale: .current)
Run Code Online (Sandbox Code Playgroud)

例子:

if let d = Decimal(string: "8.2") {
    print(d) // 8.2
}
Run Code Online (Sandbox Code Playgroud)