How to Check if Two Decimal Numbers Are Truly Equal in JavaScript
Have you ever noticed that sometimes when you add decimal numbers in a program, the result isn’t exactly what you expect?
For example, when you try to add 0.1
and 0.2
, you might get something like 0.30000000000000004
instead of the clean 0.3
. This happens because of how decimal numbers are stored inside a computer.
Computers use binary (base-2) to represent all numbers, which means every number is broken down into combinations of 1s and 0s.
Let’s take a simple decimal number, like 0.1. In the decimal system (base-10), 0.1 represents one-tenth of 1.
But in binary (base-2), it's much trickier.
In binary, numbers are represented using powers of 2, rather than powers of 10 like in the decimal system.
-
The first position after the binary point represents 1/2 (or 0.5)
-
The second position represents 1/4 (or 0.25)
-
The third position represents 1/8 (or 0.125), and so on
To represent 0.1 in binary, you need to combine these fractions. However, the result is never exact. It requires adding smaller and smaller fractions indefinitely, like this:
0.1 ≈ 1/16 + 1/32 + 1/256 + ..., forming a repeating pattern: 0.00011001100110011...
Since JavaScript uses 64-bit floating-point numbers to store decimal values, it can't store this infinite sequence of 1s and 0s precisely. As a result, 0.1 is stored as an approximation, such as 0.10000000000000000555, leading to small inaccuracies in calculations.
This is why, when you add certain numbers, you might end up with something that doesn’t match the exact decimal you expected.
let a = 0; a += 0.8; a += 0.4; console.log(a); // 1.2000000000000002 let b = 0; b += 0.6; b += 0.6; console.log(b); // 1.2
Even though a
and b
should logically be the same, a === b
returns false
because of this small precision issue.
So, since decimal values aren't stored exactly, how can we compare them?
One common way to compare decimal numbers in JavaScript is by checking if their difference is within a small range (called an "epsilon" value). This is done by setting a tolerance level, allowing for small errors due to floating-point precision.
Here's an example:
const epsilon = 0.0000001; // A small tolerance value if (Math.abs(a - b) < epsilon) { console.log("The values are effectively the same"); } else { console.log("The values are different"); }
In this case, Math.abs(a - b)
checks the difference between a
and b
. If the difference is smaller than a small tolerance (epsilon
), the numbers are considered the same.
There are also a few libraries available that you can use to handle decimal values more accurately. These libraries don’t rely on the binary floating-point format but instead use a more precise decimal-based system. This ensures that operations like addition, subtraction, multiplication, and division work as expected for decimal numbers, without hidden inaccuracies.
Some popular ones include:
-
Decimal.js
This library provides a comprehensive set of methods to work with decimal numbers. It ensures precise calculations and supports advanced features like configurable precision.const Decimal = require("decimal.js"); let a = new Decimal(0); a = a.plus(0.8); a = a.plus(0.4); // a = 1.2 let b = new Decimal(0); b = b.plus(0.6); b = b.plus(0.6); // b = 1.2 console.log(a.equals(b)); // Output: true
-
Big.js
Big.js is a lightweight library. It’s great for simple and efficient handling of numbers when you don’t need the full feature set of other libraries.const Big = require("big.js"); let a = new Big(0); a = a.plus(0.8); a = a.plus(0.4); // a = 1.2 let b = new Big(0); b = b.plus(0.6); b = b.plus(0.6); // b = 1.2 console.log(a.eq(b)); // Output: true
-
bignumber.js
This library is similar to the others but offers more advanced features, such as specifying decimal precision and working with very large numbers. It’s useful for complex calculations where fine control is needed.const BigNumber = require("bignumber.js"); let a = new BigNumber(0.1); let b = new BigNumber(0.2); let sum = a.plus(b); console.log(sum.toString()); // Output: "0.3"
Get my free, weekly JavaScript tutorials
Want to improve your JavaScript fluency?
Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.
Join today, and level up your JavaScript every Sunday!
Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.