Generates DecimalNumbers for NumberFormatter doesn't work

My function converts the string to decimal

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

      

But it doesn't work on hold. Sometimes it comes back like

Optional(8.300000000000001)
Optional(8.199999999999999)

      

instead of 8.3 or 8.2. In the string, the value is either "8.3" or "8.2", but the converted decimal value does not meet my requirements. Any suggestion where did I go wrong?

+3


source to share


1 answer


It seems to be a mistake, compare

Even if generatesDecimalNumbers

set to true

, the formatter generates a binary floating point number internally, and it cannot represent decimals such as 8.2

exactly.

Note that (unlike the documentation) the property maximumFractionDigits

has no effect when parsing a string to a number.

There is a simple solution: use

NSDecimalNumber(string: strValue) // or
NSDecimalNumber(string: strValue, locale: Locale.current)

      



depending on whether the string is localized or not.

Or with Swift 3 type Decimal

:

Decimal(string: strValue) // or
Decimal(string: strValue, locale: .current)

      

Example:

if let d = Decimal(string: "8.2") {
    print(d) // 8.2
}

      

+4


source







All Articles