Swift 3 Decimal, NSDecimal and NSDecimalNumber
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When you need exact base-10 arithmetic in Swift, the three related names you see are Decimal, NSDecimal, and NSDecimalNumber. They are connected, but they do not play the same role: Decimal is the normal Swift-friendly value type, NSDecimal is the lower-level Foundation representation, and NSDecimalNumber is the Objective-C class wrapper for decimal values.
Use Decimal for Normal Swift Arithmetic
In most Swift code, Decimal is the right default. It behaves like a value type and fits naturally into ordinary application logic.
This is especially useful for currency, quantities, and other domains where binary floating-point artifacts are unacceptable.
The Double example can expose binary floating-point approximation, while Decimal is designed for exact decimal-style arithmetic.
What NSDecimal Actually Is
NSDecimal is the lower-level C-style struct Foundation uses for decimal operations. Most Swift developers do not need to work with it directly, but it becomes relevant when you use low-level Foundation decimal functions.
This works, but it is more verbose than ordinary Decimal operators. That is why NSDecimal is usually an implementation detail or an escape hatch, not the first choice for everyday code.
When NSDecimalNumber Is Useful
NSDecimalNumber is an immutable Foundation class. It is still useful when:
- an API expects an Objective-C object
- you need Foundation rounding behavior objects
- you are interoperating with
NSNumber-oriented APIs
This is one of the clearest places where NSDecimalNumber remains convenient. It gives you object-based behavior and Foundation rounding helpers in one package.
Bridging Between Decimal and NSDecimalNumber
In real Swift code, a common pattern is:
- use
Decimalfor your business logic - bridge to
NSDecimalNumberonly when an API or Foundation helper requires it
That keeps most of the code Swift-native while still letting you interact with older Foundation and Objective-C interfaces when necessary.
The reverse also happens:
This makes it easy to cross the boundary deliberately instead of mixing the types without a plan.
Rounding Is a Separate Design Decision
Choosing a decimal type is not the same as choosing a rounding policy. Even with exact decimal arithmetic, real business logic still needs explicit rules for:
- how many fractional digits to keep
- when rounding occurs
- which rounding mode is allowed
With Decimal, a common low-level Foundation approach is NSDecimalRound:
This matters because exact decimal storage does not magically define domain rules for tax, currency display, or ledger calculations.
A Practical Rule of Thumb
For most application code, the decision rule is simple:
- use
Decimalfor ordinary Swift arithmetic - use
NSDecimalNumberwhen you need an object or Foundation rounding helpers - use direct
NSDecimalfunctions only when low-level Foundation APIs require them
That covers most situations cleanly and keeps the code readable.
If you are building a money-related domain model, this rule is especially useful because it keeps the main logic in Swift-native value semantics and limits Objective-C bridging to clear integration points.
Avoid Double in Decimal-Sensitive Domains
The most important mistake to avoid is not choosing between the three decimal types incorrectly. The bigger mistake is using Double at all when the problem domain expects decimal correctness.
For prices, invoices, tax amounts, or balances, a safer default is:
- store with
Decimal - round deliberately
- bridge to
NSDecimalNumberonly when required
That is far more predictable than letting binary floating-point become part of the business model and then patching over formatting surprises later.
Common Pitfalls
One common mistake is using Double for money and expecting exact decimal behavior.
Another pitfall is reaching for NSDecimal directly when Decimal would make the code simpler and clearer.
A third issue is mixing Decimal and NSDecimalNumber casually without being clear about why object-based bridging is needed.
Finally, even exact decimal types do not remove the need for an explicit rounding policy. That decision still belongs to your business rules.
Summary
- '
Decimalis usually the best Swift-native choice for exact decimal arithmetic.' - '
NSDecimalis the lower-level Foundation representation used by low-level decimal functions.' - '
NSDecimalNumberis the Foundation class wrapper and is useful for object-based APIs and rounding helpers.' - Prefer
Decimalfor normal Swift logic and bridge only when needed. - Decimal arithmetic still requires deliberate rounding rules in real business code.
Related reading
- Swift 3 for loop with increment
- Swift 3 URLSession.shared Ambiguous reference to member 'dataTaskwithcompletionHandler error bug
- Swift add icon/image in UITextField
- Swift add icon/image in UITextField
- Swift addsubview and remove it
- Swift Alamofire How to get the HTTP response status code
- Swift Alamofire VS AFNetworking
- Swift alert view with OK and Cancel which button tapped?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.