I have an iOS application that will be performing a lot of basic arithmetic on numbers representing USD currency (eg 25.00 representing $25.00).
I have gotten into a lot of trouble using the datatype Double in other languages like Java and Javascript so I would like to know the best datatype to use for currency in Swift.
Currency variables are stored as 64-bit (8-byte) numbers in an integer format, scaled by 10,000 to give a fixed-point number with 15 digits to the left of the decimal point and 4 digits to the right.
The best datatype to use for currency in C# is decimal. The decimal type is a 128-bit data type suitable for financial and monetary calculations. The decimal type can represent values ranging from 1.0 * 10^-28 to approximately 7.9 * 10^28 with 28-29 significant digits.
Float and double are bad for financial (even for military use) world, never use them for monetary calculations.
The best type for price column should be DECIMAL. The type DECIMAL stores the value precisely. For Example - DECIMAL(10,2) can be used to store price value. It means the total digit will be 10 and two digits will be after decimal point.
Use Decimal
, and make sure you initialize it properly!
// 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 😀 }
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 Double
s or Float
s 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 Decimal
s 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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With