In the fast-paced world of finance, precision is everything. It's always better to avoid a million$ loss because of a rounding / precision error.
When it Comes to Money, Think About Datatype
The starting point of this article is the realization that money is not your average basic number that you can use to count the apples in your basket. What do you get when you try to multiply 10€ with 10$? Tough huh… Have you ever found a miraculous $1.546 in the pocket of an old jacket? Yeah I know, this is not really possible either. These silly examples are here to illustrate the fact that money has its own particular rules and can't only be modeled by a simple number. I reassure you, I am not the first one who realized that (and maybe you did realize it way before me). In 2002, the programmer Martin Fowler proposed in the Patterns of Enterprise Application Architecture a way to represent money, with specific attributes and operand rules. For him, the two minimal viable attributes needed for a money datatype were:
amount currency
This really basic representation will be our starting point to construct a simple but robust monetary model.
Money Amounts, How to Represent Them
A money amount is definitely a particular number: it has a fixed precision (again, you can't have 4.376$ in your pocket). You need to choose a way to represent it that helps you to respect this constraint.
A Naïve Approach, the Native number JavaScript Datatype
Spoiler alert, this is definitely not a good idea if you don't want to see a few cents (if it's not dollars) disappear in the dark world of floating-points number representation.
The Costly Precision Error
If you have some experience with coding in JavaScript, you know that even the most simple calculation can result in a precision error that you would not expect at first. The most obvious and well-known example to highlight this phenomenon is:
0.1 + 0.2 !== 0.3 // true 0.1 + 0.2 // 0.30000000000000004
If this example doesn't fully convince you, I advice you to have a look at this article which deeps dive a bit further into all the problematic calculation results that you can encounter working with JavaScript native number type…
This slight delta in the results may appear harmless to you (with a magnitude of about ~ 10^-16), however in a critical financial application, such error can cascade quickly. Consider transferring funds between thousands of accounts, where each transaction involves similar calculations. The slight inaccuracies add up, and before you know it, your financial statements are off by thousands of dollars. And honestly, we can all agree that when it comes to money, error is not allowed: both legally and to build a trusting relationship with your customers.
Why Such an Error?
The first question I asked myself when encountering the issue in one of my projects is why ? I discovered that the source of the problem is not JavaScript and these imprecisions also affect other modern programming languages (Java, C, Python, …).
// In C #include <stdio.h> int main() { double a = 0.1; double b = 0.2; double sum = a + b; if (sum == 0.3) { printf("Equal\n"); } else { printf("Not Equal\n"); // This block is executed } return 0; } // > Not equal </stdio.h>
// In Java public class doublePrecision { public static void main(String[] args) { double total = 0; total += 5.6; total += 5.8; System.out.println(total); } } // > 11.399999999999
In fact, the root cause lies in the standard used by these languages to represent floating-point numbers : the double(or single)-precision floating-point format, specified by the IEEE 754 standard.
IEEE 754 Standard: a Story of Bit Representation
In Javascript, the native type number corresponds to double-precision floating-point numbers, which means that a number is encoded with 64 bits and divided into three parts:
- 1 bit for the sign
- 11 bits for the exponent
- 52 bits for the mantissa (or fraction) which ranges from 0 to 1
Then, you need to use the following formula to convert your bit representation into a decimal value:
An example of double-precision floating-point number representation, an approximation of 1/3 :
0 01111111101 0101010101010101010101010101010101010101010101010101 = (-1)^0 x (1 + 2^-2 + 2^-4 + 2^-6 + ... + 2^-50 + 2^-52) x 2^(1021-1023) = 0.333333333333333314829616256247390992939472198486328125 ~ 1/3
This format allows us to represent a vast range of values, but it can't represent every possible number with absolute precision (just between 0 and 1 you can find an infinity of numbers…). Many numbers cannot be represented exactly in binary form. To loop on the first example, that's the issue with 0.1 and 0.2. Double-point floating representation gives us an approximation of these value, so when you add these two imprecise representations, the result is also not exact.
A possible solution: Arbitrary Decimal Arithmetic
Now that you are fully convinced that handling money amounts with native JavaScript number type is a bad idea (at least I hope you begin to have doubts about it), the 1Billion$ question is how should you proceed ? A solution could be to make use of some of the powerful fixed-precision arithmetic packages available in JavaScript. For example Decimal.js (which is used by the popular ORM Prisma to represent its Decimal datatype) or Big.js.
These packages provide you with special datatypes that allow you to perform calculations with getting rid of precision errors we explained above.
// Example using Decimal.js const Decimal = require('decimal.js'); const a = new Decimal('0.1'); const b = new Decimal('0.2'); const result = a.plus(b); console.log(result.toString()); // Output: '0.3'
This approach provides you with another advantage, it drastically extends the maximum value that can be represented, which can become pretty handy when you are dealing with cryptocurrencies for example.
Even if it is really robust, that it not the one I prefer to choose to implement in my web applications. I find it easier and clearer to apply Stripe strategy to only deal with integer values.
Learn from Masters : Stripe, a No-Floating Points Strategy
We, at Theodo Fintech, value pragmatism! We love to take inspiration from the most succeeding companies in the industry. Stripe, the well-known billions$ company specialized in payment services, made the choice to handle money amounts without floating numbers but with integers. To do that, they use the smallest unit of the currency to represent a monetary amount.
// 10 USD are represented by { "amount": 1000, "currency": "USD" }
Currency Minimal Units… Are Not Consistent!
I guess that many of you already know this: all currencies don't have the smallest unit of the same magnitude. Most of them are "two-decimal" currencies (EUR, USD, GBP) which means that their smallest unit is 1/100th of the currency. However, some are "three-decimal" currencies (KWD) or even "zero-decimal" currencies (JPY). (You can find more information about it by following the ISO4217 standard). To handle these disparities, you should integrate to your money data representation the multiplicative factor to convert an amount represented in the smallest unit into the corresponding currency.
I Chose a Way to Represent Money Amount… OK, But Now, How Do I Round Them?
I guess you already figured it out, you can either work with native number , third party arbitrary-precision packages or integers, calculations can (and will) lead you to floating-point results that you will need to round to your monetary finite precision. As a quick example is never to much, let's say that you handle integer values and contracted a loan of 16k$ with a really precise interest rate of 8.5413% (ouch…). You then need to refund 16k$ plus an additional amount of
1600000 * 0.085413 // amount in cents //Output in cents: 136660.8
The crux is to properly handle the rounding process of money amounts after calculations. Most of the time, you end up having to choose between three different kinds of rounding:
- Classic rounding: Round to the closest value and if halfway between two values, round up
- Banker rounding: Round to the closest value and if halfway between two values, round down if the number is even, and round up if the number is odd (this gives you numerical stability when you have to perform lots of rounding)
- Custom rounding: based on particular legislation for the currency you use and the use case you are handling
When it comes to roundings, there is not really any "magic sauce": you need to arbitrate depending on your situation. I recommend you always check legislation when you deal with a new currency and a new rounding use case (conversion, money split, interest rates for credits, …). You better follow regulations right away to avoid further troubles. For example, when it comes to conversion rates, most currencies have determined rules about needed precision and rounding rules (you can have a look at the EUR conversion rate rules here).
Conclusion
This article is not exhaustive about all the existing possibilities to handle money amounts in JavaScript and is also not intended to give you a complete/perfect money data model. I tried to give you enough hints and guidelines to implement a representation that proved to be consistent, resilient and which was chosen by big actors of the fintech industry. I hope that you will be able to perform money amount calculations in your future projects without forgetting any cents in your pocket (otherwise don't forget to have a look in your old jacket)!
The above is the detailed content of Financial Precision in JavaScript: Handle Money Without Losing a Cent. For more information, please follow other related articles on the PHP Chinese website!

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 Chinese version
Chinese version, very easy to use

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Dreamweaver Mac version
Visual web development tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool