This is an age old problem that should be solved by using NumberFormatter
. Given a formatter:
extension NumberFormatter {
/// Currency formatter for USD only.
static let dollars: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 2
formatter.locale = Locale(identifier: "en_US")
return formatter
}()
}
Parsing a string like $0.07
as such: NumberFormatter.dollars.number(from: string)!.decimalValue
should result in an exact value. It doesn't. For some values where this fails, parsing the doubleValue
may be more precise: Decimal(NumberFormatter.dollars.number(from: string)!.doubleValue)
. However, this fails for some values too. $0.07
fails both methods. Manually parsing gives exact results: Decimal(string: String(string.dropFirst().filter { $0 != "," }))
. However, this is extremely non-localizable and rather slow.
So what's the solution here? Is there a good one?