# Creating a Money Type in Swift

The FinTech space is booming and there is a lot of buzz around development topics. So, I thought would write about how to store money using Swift. We will cover why this is even an issue in the first place and how you might address it in your code.

#### Decimal versus Binary Number Systems — The Heart of the Problem

Humans count things using base 10; computers find it easier to count using base 2 (1 and 0). Integers translate from base 10 to base 2 just fine. The problem arises with fractions. Not every base 10 fraction can be represented accurately when using base 2. Only base 10 fractions where the denominator represents a power of 2 integer can be accurately converted to an equivalent in base 2.

In the following example, we create a running tally of adding 0.01 (using *Floats*) in a loop 100 times, resulting in a sum of 1. However, we don’t get 1 due to the fact that we are using a *Float* (binary type), which can’t accurately represent the value 0.01.

How do we fix it? In Swift, you need to use *NSDecimalNumber. U*se *NSDecimalNumber *any time number precision is desired with decimals.

NSDecimalNumber, an immutable subclass of NSNumber, provides an object-oriented wrapper for doing base-10 arithmetic. An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.

Let’s look at how *NSDecimalNumber* stands up to the *Float *type in a couple of samples below.

Hopefully this makes sense. In the rest of this post, we are going to create a money type based on *NSDecimalNumber* and use it to create a simple currency converter.

#### Defining our Money Type

Our *Money* type needs to be an immutable object to hold both an amount and a currency type. I choose to create a struct to represent our *Money* type that uses an enumeration of currencies. To emphasize the connectedness of an amount and its currency, I am storing the values as a tuple within my struct. The rest of this class is defined as you might expect. There are property getters to return values, initializers to provide multiple ways to create our money, and helper functions to perform math operations. You can find the playground file with the code here.

Rounding out our *Money* struct, I created an enumeration for the currencies and an enumeration for the exchange rates. We will come back to the exchange rates in a bit. For now, I want to bring your attention to how we can wrap the awkwardness of using the *NSDecimalNumber* class with additions to our *Money* type.

The *NSDecimalNumber* class is extremely useful, but it isn’t the easiest class to work with. Yes, there are several initializers that you can use to create an instance, but using the math operations are somewhat tedious to type. In addition, you need to create *NSDecimalNumberHandlers* to let the type know how to deal with rounding, overflows, and underflows. What I really want is to seamlessly use my *Money* type without having to worry about the underlying details of *NSDecimalNumber*. I want to use the operators and even be able to mix types when adding, subtracting, etc. The way to achieve this is to use operator overloading.

In the code above, I overload the +operator to allow me to add two *NSDecimalNumbers* together in using a familiar syntax. I create additional operators to allow me to add my *Money* type to *Floats*, which can be a very handy tool to have around. I also created several other operators that you can explore on your own to reinforce their convenience and ease of creation.

Another feature we need is the ability to compare two Money types, which is accomplished using the *Comparable* protocol. We just need to add this to our Money struct and define an ==operator and a <operator. Swift will take care of the !=, >, <=, and >= operators for us.

#### Creating the Currency Converter

Now that we have our *Money* type, we can create a currency converter to convert between currencies with which you have exchange rates. In order to complete our task, we need a way to represent an exchange rate. I created a struct to conform to the *Hashable* protocol because I want to store my exchange rates in a *Set *since it doesn’t allow duplicates, and order doesn’t matter to me. Our exchange rate struct only has three properties: *CurrencyOne*, *CurrencyTwo*, and *rate*. In addition, there is a computed property *inverseRate* to return the inverse of the exchange rate in cases where the currencies are reversed.

Our currency converter is pretty basic. I added a static *Set* to the *Money* type that holds exchange rates. To do the conversions, I created a function *amountIn(currency: Currency)->Money* on the *Money* type to check for the appropriate exchange rate in the set and then make the conversion, returning a new *Money* type.

Check out the code below to see you how can use the Money struct and to also see the currency conversions in action. I implemented the *CustomStringConvertible* protocol to make my structs more readable in the margins.

#### Wrapping Up

We just completed creating a *Money* type that uses base 10 math operations for precision and that knows its currency type. We can use our *Money* type like our numerical types, and we can even mix them with base 2 types like *Floats*. I’ll leave it to you to extend this type for your own purposes. Again, you can find the playground file here.

On a lighter note, I also wrote an article on why creating native apps is probably the best way to go in most of your mobile development endeavors. Read it and weigh in the discussion!

**Your Hybrid App is Going to Kill You**

*If your company only makes hybrid apps, you are going to lose in the end; it’s just a matter of time. Hybrid mobile…*medium.com

If you find this post helpful, recommend it for others to read. You can visit me at www.gittielabs.com and subscribe to my RSS feed so that you won’t miss a post. I’m also putting together a video course to teach Swift development and could use your input on topics you feel would be helpful. Thanks for reading!