NSDecimalNumber和货币-Swift

Lat*_*ate 2 currency nsdecimalnumber ios swift

我读了很多书,这NSDecimalNumber是使用货币时最好的格式。

但是,我仍然遇到浮点问题。

例如。

let a: NSDecimalNumber = 0.07 //0.07000000000000003
let b: NSDecimalNumber = 7.dividing(by: 100) //0.06999999999999999
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用Decimal,b就是我期望的:

let b: Decimal = 7 / 100 //0.07
Run Code Online (Sandbox Code Playgroud)

我在我的应用程序中使用核心数据。所以我坚持NSDecimalNumber。除非我想将很多转换NSDecimalNumbersDecimals

有人可以帮我得到0.07吗?

Rob*_*Rob 8

问题是您正在有效地进行浮点数学运算(存在的问题是它忠实地捕获了Double)中的小数十进制值,并根据已经引起这种差异的值创建了Decimal(或NSDecimalNumberDouble。相反,您想Decimal在进行除法之前(或在拥有小数之前Double,即使是文字)也要创建值。

因此,下面的示例等效于您的示例,该示例将构建的Double表示形式(带有相应的限制)0.07,最终您得到的值不完全是0.07

let value = Decimal(7.0 / 100.0)                                // or NSDecimalNumber(value: 7.0 / 100.0)
Run Code Online (Sandbox Code Playgroud)

而这不会遇到此问题,因为我们将十进制除以7十进制100

let value = Decimal(7) / Decimal(100)                           // or NSDecimalNumber(value: 7).dividing(by: 100) 
Run Code Online (Sandbox Code Playgroud)

或者,其他可创造0.07价值但Double在流程中避免使用的方法包括使用字符串:

let value = Decimal(string: "0.07")                             // or NSDecimalNumber(string: "0.07")
Run Code Online (Sandbox Code Playgroud)

或指定尾数/有效数和指数:

let value = Decimal(sign: .plus, exponent: -2, significand: 7)  // or NSDecimalNumber(mantissa: 7, exponent: -2, isNegative: false)
Run Code Online (Sandbox Code Playgroud)

最重要的Double是,在使用Decimal(或NSDecimalNumber)时完全避免使用表示形式,这样就不会遇到您描述的问题。