我有一个iOS应用程序,将对代表美元货币的数字执行大量基本算术(例如25.00代表25.00美元)。
我在使用Java和Javascript等其他语言的数据类型Double时遇到了很多麻烦,所以我想知道在Swift中用于货币的最佳数据类型。
使用NSDecimalNumber
(more info here)。例:
let a = NSDecimalNumber(integer: 123456)
let b = NSDecimalNumber(integer: 1000)
let c = a.decimalNumberByDividingBy(b)
println(c)
// Result: "123.456"
您可能希望使用an extension like this one将运算符重载添加到NSDecimalNumber
类。
有一个非常好的名为Money的lib:
let money: Money = 100
let moreMoney = money + 50 //150
除此之外还有许多不错的功能,例如类型安全的货币:
let euros: EUR = 100
let dollars: USD = 1500
euros + dollars //Error
二进制运算符'+'不能应用于'EUR'(又名'_Money')和'USD'(又名'_Money')类型的操作数
使用Decimal
,并确保正确初始化它!
// 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 😟
}
在表示货币金额的Double
s或Float
s上执行算术运算将产生不准确的结果。这是因为Double
和Float
类型无法准确表示大多数十进制数。 More information here。
底线:使用Decimal
s或Int
对货币金额执行算术运算