13

I am writing a Swift app and am dealing with decimals in a database (stored in mysql as decimals, with 2 digits. Basically it's sales someone made each day, so generally anything from $0 to $1000, but not millions, and nothing insane in terms of trailing decimals, just always rounded to 2 decimal places).

Referencing this helped me out: How to properly format currency on ios

..But I wanted to just do a quick sanity check here and make sure this strategy is ok. i.e I would use NSDecimal or NSDecimalNumber (is there a preferred swift equivalent??)

What would you all recommend I do when dealing with currency in Swift? I'd like to use the locale-based currency symbol as well. I have a class called Sales that contains the amount in question. What do you recommend the datatype to be?

Apologies if I am coming off lazy, I actually have some ideas on what to do but feel a little overwhelmed at the "right" approach, especially in a locale-sensitive way, and wanted to check in here with you all.

Thanks so much!

Community
  • 1
  • 1
NullHypothesis
  • 4,286
  • 6
  • 37
  • 79

2 Answers2

12

Update for Swift 3: A Decimal type is now available with built-in support for operators like *, /, +, <, etc. When used in an Any context (passed to Objective-C), it's bridged to NSDecimalNumber.


Old answer:

NSDecimal is not really supported in Swift (it's a weird opaque pointer type), but NSDecimalNumber is — and as in Obj-C, it's the best thing to use for base-ten arithmetic (because it actually does its operations in base ten). NSLocale, NSNumberFormatter and friends all work too and should satisfy your localization needs.

Kirill Titov
  • 2,060
  • 5
  • 21
  • 33
jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • Thanks so much! So you would recommend my class properties to be NSDecimalNumber and not of type Decimal, correct? When I am converting a string that looks like "5000.52" to a NSDecimalNumber, are there any special rules to consider? – NullHypothesis Aug 14 '14 at 00:28
  • What do you mean by Decimal? I would recommend the [Number and Value Programming Topics](https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Conceptual/NumbersandValues/NumbersandValues.html#//apple_ref/doc/uid/10000038i) guide. – jtbandes Aug 14 '14 at 00:29
  • sorry I meant 'Double'!! – NullHypothesis Aug 14 '14 at 00:30
  • Of course it depends what you are doing, but you should [understand floating-point binary rounding error](http://floating-point-gui.de/formats/binary/) — and know that if your numbers are in base ten then NSDecimal(Number) does not have the same problems because it represents base-ten numbers natively. – jtbandes Aug 14 '14 at 00:34
  • To clarify, "5000.52" would be represented by NSDecimal as 500052×10^-2 but in a regular IEEE floating point number as 1.220830078×2^12. – jtbandes Aug 14 '14 at 05:35
  • thank you! So NSDecimalNumber and NSNumberFormat are the right way to do it – NullHypothesis Aug 14 '14 at 05:36
3

Swift 3 now has a Decimal (value) type which is bridged to NSDecimalNumber.

Jon Hull
  • 679
  • 6
  • 15