[英]Swift NumberFormatter formatting all values to 3 decimal places?
[英]Large decimal number formatting using NumberFormatter in Swift
我这样做是为了格式化数字,但它对大数字失败
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
if let number = formatter.number(from: "123456789123456789123") , let str = formatter.string(from:number){
print(number)
print(str)
}
它打印
123456789123456800000
123,456,789,123,456,800,000
它应该打印
123456789123456789123
123,456,789,123,456,789,123
我认为应该是数字溢出,有没有其他方法可以实现这种事情。
这个问题的根源是三方面的:
因此,当使用 Decimals 表示精度超过 17 位的数字时,千万不要做任何会将 Decimal 的值转换为 Double 的事情。 这包括用文字初始化:
print (Decimal(1234567890.12345678901234567890))
// 1234567890.1234569216
print (Decimal(string: "1234567890.12345678901234567890")!)
// 1234567890.12345678901234567890
Decimal(1234567890.12345678901234567890) 产生值 1234567890.1234569216 因为 1234567890.12345678901234567890 是一个 Double 文字,精度限制为大约 17 位数字。
遗憾的是,NumberFormatter 显然从未收到有关此问题的备忘录。
var dec = Decimal(string: "1234567890.12345678901234567890")!
let f = NumberFormatter()
f.numberStyle = .decimal
f.minimumFractionDigits = 20
print (f.string(from: dec as NSDecimalNumber)!) // 1,234,567,890.12346000000000000000
所以目前,没有办法让 Swift 准确地产生精度超过 17 位的本地化十进制数字。 例如,NumberFormatter 无法生成字符串 1,234,567,890.12345678901234567890,即使 Decimal 可以表示该精确值。
您可以使用 String(describing:)
print (String(describing:(Decimal(string: "1234567890.12345678901234567890")!)))
// 1234567890.1234567890123456789
对于我自己的一个应用程序,我制作了一个“穷人的”小数格式器,它使用所需区域设置中的小数点分隔符简单地输出完整值:
let locale = Locale(identifier: "fr_FR")
dec = Decimal(string: "1234567890,12345678901234567890", locale: locale)!
let formatter = NumberFormatter()
formatter.locale = locale
let localizedSeparator = String(formatter.decimalSeparator.first ?? ".")
let fractionDigits = 20
var strings = String(describing:(dec)).split(separator: (Locale.current.decimalSeparator?.first) ?? "." )
var result = strings[0]
if fractionDigits > 0 {
if strings.count > 1 {
while strings[1].count < fractionDigits { strings[1] += "0" }
result += localizedSeparator + String(strings[1].prefix(fractionDigits))
}
else {
result += localizedSeparator + (0..<fractionDigits).map{_ in "0"}
}
}
print (result) // 1234567890,12345678901234567890
您可以显式创建一个Decimal
来解决提到的错误
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
if let decimalNumber = Decimal(string: "123456789123456789123"), let str = formatter.string(from:decimalNumber as NSNumber) {
print(decimalNumber)
print(str)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.