我应该使用 NSDecimalNumber 来处理金钱吗? [英] Should I use NSDecimalNumber to deal with money?

查看:19
本文介绍了我应该使用 NSDecimalNumber 来处理金钱吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我开始编写我的第一个应用程序时,我不假思索地将 NSNumber 用于货币价值.然后我想也许 c 类型足以处理我的价值观.然而,我在 iPhone SDK 论坛中被建议使用 NSDecimalNumber,因为它具有出色的舍入能力.

As I started coding my first app I used NSNumber for money values without thinking twice. Then I thought that maybe c types were enough to deal with my values. Yet, I was advised in the iPhone SDK forum to use NSDecimalNumber, because of its excellent rounding capabilities.

不是气质上的数学家,我认为尾数/指数范式可能有点矫枉过正;仍然,谷歌搜索,我意识到大多数关于可可中的货币/货币的讨论都提到了 NSDecimalNumber.

Not being a mathematician by temperament, I thought that the mantissa/exponent paradigm might be overkill; still, googlin' around, I realised that most talks about money/currency in cocoa were referred to NSDecimalNumber.

请注意,我正在开发的应用程序将国际化,因此以美分计算金额的选项实际上并不可行,因为货币结构在很大程度上取决于所使用的语言环境.

Notice that the app I am working on is going to be internationalised, so the option of counting the amount in cents is not really viable, for the monetary structure depends greatly on the locale used.

我 90% 确定我需要使用 NSDecimalNumber,但由于我在网上找不到明确的答案(例如:如果您处理金钱,请使用 NSDecimalNumber!")我想我会在这里问.也许答案对大多数人来说是显而易见的,但我想在开始大规模重构我的应用程序之前确定.

I am 90% sure that I need to go with NSDecimalNumber, but since I found no unambiguous answer on the web (something like: "if you deal with money, use NSDecimalNumber!") I thought I'd ask here. Maybe the answer is obvious to most, but I want to be sure before starting a massive re-factoring of my app.

说服我:)

推荐答案

Marcus Zarra 对此有很明确的立场:"如果您要处理货币,那么您应该使用 NSDecimalNumber." 他的文章启发了我查看 NSDecimalNumber,我对它印象非常深刻.处理 base-10 数学时的 IEEE 浮点错误已经让我恼火了一段时间 (1 * (0.5 - 0.4 - 0.1) = -0.00000000000000002776) 而 NSDecimalNumber 消除了它们.

Marcus Zarra has a pretty clear stance on this: "If you are dealing with currency at all, then you should be using NSDecimalNumber." His article inspired me to look into NSDecimalNumber, and I've been very impressed with it. IEEE floating point errors when dealing with base-10 math have been irritating me for a while (1 * (0.5 - 0.4 - 0.1) = -0.00000000000000002776) and NSDecimalNumber does away with them.

NSDecimalNumber 不只是添加另外几位二进制浮点精度,它实际上是进行以 10 为基数的数学运算.这消除了上面示例中显示的错误.

NSDecimalNumber doesn't just add another few digits of binary floating point precision, it actually does base-10 math. This gets rid of the errors like the one shown in the example above.

现在,我正在编写一个符号数学应用程序,所以我对 30+ 十进制数字精度和没有奇怪的浮点错误的渴望可能是一个例外,但我认为值得一看.这些操作比简单的 var = 1 + 2 样式数学更笨拙,但它们仍然易于管理.如果您担心在数学运算期间分配各种实例,NSDecimal 是 NSDecimalNumber 的 C 结构等效项,并且有 C 函数可以使用它执行完全相同的数学运算.根据我的经验,除了最苛刻的应用程序(3,344,593 次添加/秒,MacBook Air 上的 254,017 次添加/秒,281,555 次添加/秒,iPhone 上的 12,027 次添加/秒),这些都足够快了.

Now, I'm writing a symbolic math application, so my desire for 30+ decimal digit precision and no weird floating point errors might be an exception, but I think it's worth looking at. The operations are a little more awkward than simple var = 1 + 2 style math, but they're still manageable. If you're worried about allocating all sorts of instances during your math operations, NSDecimal is the C struct equivalent of NSDecimalNumber and there are C functions for doing the exact same math operations with it. In my experience, these are plenty fast for all but the most demanding applications (3,344,593 additions/s, 254,017 divisions/s on a MacBook Air, 281,555 additions/s, 12,027 divisions/s on an iPhone).

作为一个额外的好处,NSDecimalNumber 的 descriptionWithLocale: 方法提供了一个带有数字本地化版本的字符串,包括正确的十进制分隔符.其 initWithString:locale: 方法也是如此.

As an added bonus, NSDecimalNumber's descriptionWithLocale: method provides a string with a localized version of the number, including the correct decimal separator. The same goes in reverse for its initWithString:locale: method.

这篇关于我应该使用 NSDecimalNumber 来处理金钱吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆