Up to date
Published
4 min read

Trevor I. Lasn

Staff Software Engineer, Engineering Manager

Precise Decimal Math in JavaScript with Fraction.js

How to handle exact decimal calculations in JavaScript when floating-point precision isn't good enough

Ever tried to do precise calculations in JavaScript? These issues can cause serious problems, especially when dealing with money, percentages, or any calculations that need to be exact.

This isn’t a JavaScript bug. It’s a fundamental limitation of how computers store decimal numbers, and it affects nearly every programming language. To understand why we need Fraction.js, we first need to understand what’s really happening under the hood.

Computers store numbers in binary (base-2). While this works perfectly for whole numbers, it creates problems with decimals.

In base-10 (our decimal system), we can represent 1/10 simply as 0.1. But in binary, 0.1 is a repeating fraction - like trying to represent 1/3 in decimal (0.333333…). When this gets stored in JavaScript’s 64-bit floating-point format (IEEE 754), it has to be truncated, leading to tiny rounding errors.

You might think BigInt could solve this problem, but it has its own limitations:

BigInt solves precision for whole numbers but can’t handle decimals at all. It’s designed for different use cases like cryptography or very large integer calculations.

A common workaround is to multiply everything by 100 to avoid decimals entirely:

This approach looks simple but falls apart with complex calculations or multiple operations.

Working with Fractions Instead of Decimals

Let’s solve these precision problems using Fraction.js:, a library that handles numbers as fractions instead of floating-point decimals. Just like we learned math in school: 1/3 is more precise than 0.333333.

Fraction.js uses a BigInt representation for both the numerator and denominator, ensuring minimal performance overhead while maximizing accuracy. Its design is optimized for precision, making it an ideal choice as a foundational library for other math tools, such as Polynomial.js and Math.js

Instead of trying to represent decimals in binary, which causes those rounding errors we saw earlier, Fraction.js stores each number as a ratio of whole numbers. For example, 0.1 becomes 1/10 internally. This means our calculations stay exact, just like they would on paper.

Understanding the Limitations

Fraction.js is powerful, but it’s not magic. It works with rational numbers - numbers that can be expressed as a ratio of integers (like 3/4 or 22/7). This makes it perfect for money calculations or simple fractions, but not so great for irrational numbers like π or √2.

While it uses BigInt internally, you’re still working with JavaScript’s number system at the edges.

This means you get more precision than regular decimals, but not infinite precision. Some operations have limitations too. Square roots give approximations rather than exact values, and transcendental functions like sin or cos aren’t supported. Complex numbers are also off the table.

Even with these limitations, Fraction.js is incredibly useful. You can use it to calculate exact values ahead of time, handle money calculations without rounding errors, build educational software that works with fractions, or solve any problem where decimal precision really matters. The key is knowing when to use it and when something else might be more appropriate.


Found this article helpful? You might enjoy my free newsletter. I share dev tips and insights to help you grow your coding skills and advance your tech career.

Interested in supporting this blog in exchange for a shoutout? Get in touch.


Liked this post?

Check out these related articles that might be useful for you. They cover similar topics and provide additional insights.

Javascript
3 min read

JavaScript's &&= Operator: Understanding Logical AND Assignment

Use the &&= operator to safely update truthy values while preserving falsy states

Nov 5, 2024
Read article
Javascript
4 min read

Embrace Intermediate Variables and Early Returns in JavaScript

Early returns and intermediate variables make your code easier to reason about

Aug 30, 2024
Read article
Javascript
3 min read

Float16Array in JavaScript

Understanding the new 16-bit floating point array in JavaScript

Apr 14, 2025
Read article
Javascript
7 min read

JavaScript Operators: '||' vs '&&' vs '??'

Master JavaScript logical operators with practical examples and best practices

Oct 26, 2024
Read article
Javascript
7 min read

How JavaScript Was Written Back In the Day

Have you ever been curious how JavaScript was written back in the day? I was, so I dug into some of the early frameworks and libraries to see what I could learn.

Jun 12, 2025
Read article
Javascript
7 min read

JavaScript Truthy and Falsy: A Deep Dive

Grasp JavaScript's type coercion with practical examples and avoid common pitfalls

Oct 27, 2024
Read article
Javascript
4 min read

The Only Widely Recognized JavaScript Feature Ever Deprecated

The 'with' statement is the only feature ever deprecated in JavaScript

Aug 22, 2024
Read article
Javascript
9 min read

Exploring JavaScript Symbols

Deep dive into JavaScript Symbols - what they are, why they matter, and how to use them effectively

Nov 15, 2024
Read article
Javascript
7 min read

WeakRefs in JavaScript: Explained In Simple Terms

Understanding how WeakRef helps manage memory in JavaScript

Jan 7, 2025
Read article

This article was originally published on https://www.trevorlasn.com/blog/fraction-numbers-in-javascript. It was written by a human and polished using grammar tools for clarity.