Why JavaScript Has Floating-Point Precision Issues (and How to Fix Them)
Have you ever written a perfectly reasonable line of JavaScript like 0.1 + 0.2 and gotten back 0.30000000000000004? It feels almost mocking—how can a language built for the modern web fail at such basic math? The truth is, JavaScript isn’t bad at math at all. It’s extremely precise. The surprise comes from what kind of math it’s doing. Under the hood, JavaScript uses the same binary floating-point system found in most programming languages and even tools like Excel. And that system, while powerful, was never designed to represent everyday decimal numbers cleanly.
JavaScript Uses IEEE 754 Binary Floating-Point
JavaScript represents all regular numbers using the IEEE 754 double-precision floating-point format. This gives it an enormous range and fast performance, but it comes with a catch: most decimal fractions cannot be represented exactly in binary.
Numbers like 0.5 or 0.25 convert neatly into binary. But 0.1 is like 1/3 in base-10—an endlessly repeating value. So JavaScript stores the closest possible approximation, not the exact number you typed.
When you write:
Js
you are really adding two approximations, and the tiny leftover error shows up as:
Js
That microscopic difference is the root of nearly every JavaScript “math bug” you see online.
Tiny Errors, Real-World Problems
On their own, these errors are incredibly small. But software doesn’t care how small an error is—only whether it exists.
They start to matter when you:
- compare numbers for equality
- accumulate totals
- calculate taxes, discounts, or balances
For example:
Js
That extra fraction can break validations, cause off-by-a-cent bugs, and slowly corrupt financial data.
The First Line of Defense: Proper Rounding
Because floating-point errors are unavoidable, the most basic rule is simple:
Always round monetary values deliberately.
A common pattern is rounding to two decimal places at defined boundaries:
Js
This doesn’t remove floating-point arithmetic—but it controls it. The key is to round consistently, rather than letting tiny errors drift through your system.
A Better Pattern: Work in Integers (Cents)
In most professional systems, money is not stored as floating-point numbers at all.
Instead, values are stored in the smallest unit, such as cents:
Js
Only when displaying the value do you convert back:
Js
This approach avoids floating-point errors entirely in your business logic.
How Excel Handles the Same Problem
Excel also uses IEEE 754 floating-point under the hood. It has the same representation issues JavaScript does.
What makes Excel feel more reliable is not different math—it’s discipline:
- It formats numbers to fixed decimal scales
- It rounds aggressively at calculation and display boundaries
- It provides explicit rounding functions like
ROUND,MROUND, andROUNDUP
Effectively, Excel treats financial values as floating-point numbers constrained to decimal rules. JavaScript gives you the raw engine—but leaves the responsibility to you.
Professional-Grade Solutions in JavaScript
For serious financial or scientific work, developers usually go further:
Decimal libraries
Libraries like decimal.js, big.js, or bignumber.js store numbers in base-10 instead of base-2, allowing truly exact decimal arithmetic.
Js
Integer-based models
Store cents, basis points, or scaled integers everywhere.
BigInt with scaling
Useful for extremely large or precise values when paired with a fixed scale.
Practical Guidelines
- Never directly trust floating-point results for money
- Round intentionally and consistently
- Store monetary values as integers when possible
- Use decimal libraries for accounting or billing systems
- Format numbers only at system boundaries (UI, reports, exports)
JavaScript’s floating-point behavior isn’t a flaw—it’s a design choice inherited from decades of computing. The real danger isn’t that 0.1 + 0.2 is slightly wrong. It’s assuming it will ever be perfectly right.
Once you understand how IEEE 754 works and apply disciplined rounding or decimal strategies—much like Excel does—you can write financial code that is both predictable and trustworthy.












