Which Swift datatype do I use for currency

Use Decimal, and make sure you initialize it properly!

CORRECT


// Initialising a Decimal from a Double:
let monetaryAmountAsDouble = 32.111
let decimal: Decimal = NSNumber(floatLiteral: 32.111).decimalValue
print(decimal) // 32.111  😀
let result = decimal / 2
print(result) // 16.0555 😀


// Initialising a Decimal from a String:
let monetaryAmountAsString = "32,111.01"

let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "en_US")
formatter.numberStyle = .decimal

if let number = formatter.number(from: monetaryAmountAsString) {
    let decimal = number.decimalValue
    print(decimal) // 32111.01 😀
    let result = decimal / 2.1
    print(result) // 15290.9571428571428571428571428571428571 😀
}

INCORRECT

let monetaryAmountAsDouble = 32.111
let decimal = Decimal(monetaryAmountAsDouble) 
print(decimal) // 32.11099999999999488  😟

let monetaryAmountAsString = "32,111.01"
if let decimal = Decimal(string: monetaryAmountAsString, locale: Locale(identifier: "en_US")) {
    print(decimal) // 32  😟
}

Performing arithmetic operations on Doubles or Floats representing currency amounts will produce inaccurate results. This is because the Double and Float types cannot accurately represent most decimal numbers. More information here.

Bottom line: Perform arithmetic operations on currency amounts using Decimals or Int


I suggest you start with a typealias for Decimal. Example:

typealias Dollars = Decimal
let a = Dollars(123456)
let b = Dollars(1000)
let c = a / b
print(c)

Output:

123.456

If you are trying to parse a monetary value from a string, use a NumberFormatter and set its generatesDecimalNumbers property to true.

Tags:

Ios

Swift