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.