我使用哪种Swift数据类型作为货币

时间:2015-02-09 23:03:22

标签: ios swift

我有一个iOS应用程序,它会对代表美元货币的数字执行大量基本算术运算(例如25.00代表25.00美元)。

我在使用Java和Javascript等其他语言的数据类型Double时遇到了很多麻烦,所以我想知道在Swift中用于货币的最佳数据类型。

5 个答案:

答案 0 :(得分:23)

使用NSDecimalNumbermore 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类。

答案 1 :(得分:5)

有一个非常好的名为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')

类型的操作数

答案 2 :(得分:5)

使用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  
}

在代表货币金额的DoubleFloat上执行算术运算将产生不正确的结果。是因为DoubleFloat类型不能准确表示大多数十进制数字。 More information here

底线: 使用DecimalInt

对货币金额执行算术运算

答案 3 :(得分:0)

Flight-School/Money 可能是资金充裕的项目的最佳选择。

ending of README 中,@mattt 为简单的 Money 类型提供了一个很好的解决方案:

struct Money {
    enum Currency: String {
      case USD, EUR, GBP, CNY // supported currencies here
    }

    var amount: Decimal
    var currency: Currency
}

“Flight School Guide to Swift Numbers”中的第 3 章提供了对该主题的出色介绍。

答案 4 :(得分:0)

我们使用这种方法,Currency 是一个预先生成的巨大枚举(不要忘记货币值只是一个没有货币的数字 - 它们都属于一起):

struct Money: Hashable, Equatable {

    let value: Decimal
    let currency: Currency
}

extension Money {

    var string: String {
        CurrencyFormatter.shared.string(from: self)
    }
}