Ariane 5 Rocket Launcher Crash

In 1996, the European Space Agency lost a valuable shuttle just 37 seconds into the launch sequence. After a deep dive into the root cause analysis, here is a direct excerpt from their report:

The internal SRI* software exception was caused during execution of a data conversion from 64-bit floating point to 16-bit signed integer value. The floating point number which was converted had a value greater than what could be represented by a 16-bit signed integer.

Basically, the navigation software of the rocket malfunctioned due to a simple conversion error – a concept that is taught in undergrad programming classes.

While not of the same caliber, currency conversion within your software can cause the same TYPE of problems – related in effect, to the ‘type’ of the storage variable used.  We all know that trying to store Decimals as integers is a bad idea – for e.g. storing $10.3 as $10 – would lose 30 cents on every single transaction. In the same manner, storing any currency in the FLOAT type (which is what ALL programmers tend to start with), is a mistake. The DECIMAL class was invented for just this purpose. As this article will demonstrate, even that though, is not always sufficient.

As a first step, when dealing with Currencies, use the Decimal type

Floats are imprecise. Doubles are more precise than floats – but still not completely precise. Which means that if you start using floats (or doubles) to handle currency types, chances are you are losing precision – and therefore losing money. Here is a simple example:

Say you have a $100 which you have to divide 3 ways. You end up with $33.33  a piece. If you multiply this again by 3 – you do not end up with your $100. You just lost 0.01 cents because of your conversion. You could argue that – Let us keep more decimal places. So, instead of 33.33, we have 33.33333333.

There are two problems here:

  1. The number of decimal places you specify cannot be unlimited.
  2. Even if you specify a LOT of decimal places, you will still lose money when dealing with larger starting amounts (instead of $100, if we started with $100,000 for example).

The problem above is exactly what computers face when trying to store any number. A float is only an approximate representation of a number. A double, though better than a float, is still approximate. To get around this problem, C# (.NET) defines a Decimal type. The

Decimal d = 100.00M; // The M is what tells us that this is a ‘literal’ type – which is different from double, float
// divide by 3
Decimal div = d / 3;
// multiply by 3 (should get back 100.00 or as close as possible)
Decimal product = div * d;

As a second step, use a special Money type (Full Source Code available at end of article)

The Decimal solution is better, but not perfect. There is still some loss of precision.  Ideally, one should implement the Money pattern (as described in this book). Just such an implementation can be found here.  Using this Money class, all a client needs to do is:

Money usDollars = new Money(100m, “en-us”);
Money convertedCanadianDollars = new Money(usDollars.Amount * 1.12565m, “en-CA”);

Summary

We should end up with a number as close to our starting number as possible with the use  Decimal.  However, even a Decimal isn’t perfect. The best solution is to use the Money class ( a special class designed to handle currency representation and conversion). The Money class will ensure as close to 100% precision as possible when dealing with currency applications.

If only the Ariane 5 could have it’s navigation module code rewritten to include a ‘Latitude’ and a ‘Longitude’ class….

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.