Skip to content

Mindcomb · Coding

Why 0.1 + 0.2 is not 0.3

Curated by Mindcomb

Prompt

Why does 0.1 + 0.2 === 0.3 return false in JavaScript, and how should I compare decimal numbers instead?

Mindcomb ran and reviewed this comparison for the public library. It was not saved by a community member.

Prompt source
Mindcomb
License
Mindcomb original
Retrieved
Fork this combTry this promptNo winner picked · recorded cost $0.04639
Compare answers word by word

Community preferences

Which answer would you choose? Your preference is separate from the author's pick and appreciation.

Loading community preferences…

Claude Sonnet 5.5

Why 0.1 + 0.2 !== 0.3

The cause

JavaScript numbers are IEEE 754 double-precision binary floating-point values. Computers store them in base 2, and just as 1/3 can't be written exactly in decimal (0.3333…), values like 0.1 and 0.2 can't be written exactly in binary. They become repeating fractions that get rounded to the nearest representable value.

0.1 + 0.2;            // 0.30000000000000004
0.1 + 0.2 === 0.3;    // false

You can see the hidden error with toPrecision:

(0.1).toPrecision(20); // "0.10000000000000000555"
(0.2).toPrecision(20); // "0.20000000000000001110"
(0.3).toPrecision(20); // "0.29999999999999998890"

The sum of the two stored approximations lands on a different double than the one nearest to 0.3, so the strict comparison fails. This isn't a JavaScript bug. Python, Java, C, and most other languages behave the same way.

How to compare instead

1. Epsilon comparison (most common)

Check whether the numbers are close enough:

function nearlyEqual(a, b, epsilon = Number.EPSILON) {
  return Math.abs(a - b) < epsilon;
}

nearlyEqual(0.1 + 0.2, 0.3); // true

Number.EPSILON (≈ 2.22e-16) is the gap between 1 and the next representable double. It works well for values near 1, but it's too small for large numbers and too large for tiny ones. For a more robust approach, use a relative tolerance:

function nearlyEqual(a, b, relTol = 1e-9, absTol = 1e-12) {
  return Math.abs(a - b) <= Math.max(relTol * Math.max(Math.abs(a), Math.abs(b)), absTol);
}

2. Use integers for money or fixed precision

Work in the smallest unit (e.g. cents) so arithmetic is exact:

const total = 10 + 20;      // 10 cents + 20 cents
total === 30;               // true
(total / 100).toFixed(2);   // "0.30" for display

3. Round before comparing

Math.round((0.1 + 0.2) * 100) / 100 === 0.3; // true
// or
+(0.1 + 0.2).toFixed(2) === 0.3;             // true

This is fine for display or when you know the precision you need, but it's less general than a tolerance check.

4. Use a decimal library

For financial or scientific code that needs exact decimal behavior, use a library such as decimal.js, big.js, or bignumber.js:

import Decimal from 'decimal.js';
new Decimal(0.1).plus(0.2).equals(0.3); // true

For integers beyond 2^53, use native BigInt.

Quick guidance

SituationApproach
General floating-point mathTolerance comparison
CurrencyIntegers (cents) or a decimal library
Display onlytoFixed() / Intl.NumberFormat
Arbitrary precisiondecimal.js / big.js

Rule of thumb: never use === on the results of floating-point arithmetic unless you know the values are exactly representable (like integers or powers of two such as 0.5 and 0.25).

Server-recorded answer

Model: claude-sonnet-5-5

8.5s · 1,232 tok · $0.0119

Gemini 4 Argon

The reason 0.1 + 0.2 === 0.3 returns false in JavaScript has to do with how computers store numbers in binary. In fact, in JavaScript:

console.log(0.1 + 0.2); // Outputs: 0.30000000000000004

Here is why this happens and how you can fix it.


The "Why": Binary Floating-Point Math

JavaScript (like Python, Java, C++, and most other languages) uses the IEEE 754 standard for floating-point arithmetic.

Humans use a Base-10 (decimal) system, while computers use a Base-2 (binary) system.

In Base-10, it is impossible to accurately write the fraction $1/3$. You end up with a repeating decimal: 0.3333333.... Eventually, you have to round it off.

In Base-2, the exact same problem happens with the fraction $1/10$ (which is 0.1). In binary, 0.1 is an infinitely repeating number (0.0001100110011...).

Because computers have a finite amount of memory (64 bits for JavaScript numbers), they have to round that binary number off. When you add the rounded binary version of 0.1 to the rounded binary version of 0.2, the rounding errors stack up, resulting in 0.30000000000000004.


How to Compare Decimal Numbers Instead

Depending on what you are building, there are four main ways to handle this.

In computer science, the standard way to compare floating-point numbers is to check if they are "close enough" to each other, rather than strictly equal.

JavaScript provides Number.EPSILON, which represents the smallest possible difference between two representable numbers (roughly $2.22 \times 10^{-16}$).

function areEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}

console.log(areEqual(0.1 + 0.2, 0.3)); // true

(Note: If you are working with numbers much larger than 1, you may need to scale the epsilon value, or use a slightly larger margin of error like 1e-10).

2. For money and finance: Scale to Integers

If you are dealing with money, you cannot afford rounding errors. The best practice is to avoid decimals entirely by working in the smallest currency unit (like cents) and only converting to decimals when displaying to the user.

// Instead of $0.10 + $0.20, use 10 cents + 20 cents
let priceA = 10; 
let priceB = 20;
let total = priceA + priceB;

console.log(total === 30); // true
console.log("$" + (total / 100).toFixed(2)); // "$0.30"

3. For UI and simple rounding: Use .toFixed()

If you know the exact precision you need (e.g., two decimal places), you can round the numbers before comparing them.

toFixed() converts the number to a string and rounds it. You can put a + in front of it (or wrap it in Number()) to turn it back into a number.

let sum = 0.1 + 0.2;

// Round to 2 decimal places and convert back to a number
console.log(+sum.toFixed(2) === 0.3); // true

4. For heavy financial/scientific apps: Use a Library

If you are doing complex math where precision is critical, do not use standard JavaScript numbers. Use a library specifically designed for arbitrary-precision decimal arithmetic, such as:

  • decimal.js
  • big.js
  • bignumber.js

Example using Big.js:

import Big from 'big.js';

let a = new Big(0.1);
let b = new Big(0.2);
let c = a.plus(b);

console.log(c.eq(0.3)); // true

Server-recorded answer

Model: gemini-4-argon

13.5s · 1,082 tok · $0.01032

GPT-5.5

In JavaScript, numbers are usually stored as IEEE 754 double-precision binary floating-point values. Many decimal fractions cannot be represented exactly in binary, including 0.1, 0.2, and 0.3.

So this:

0.1 + 0.2

actually produces something very close to:

0.30000000000000004

Therefore:

0.1 + 0.2 === 0.3

is false, because === checks for exact numeric equality.

How to compare decimal numbers

Use a tolerance, often called an epsilon:

function nearlyEqual(a, b, epsilon = Number.EPSILON) {
  return Math.abs(a - b) < epsilon;
}

console.log(nearlyEqual(0.1 + 0.2, 0.3)); // true

However, Number.EPSILON is very small and works best for numbers near 1. For larger numbers, use a scaled tolerance:

function nearlyEqual(a, b, epsilon = Number.EPSILON) {
  return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
}

console.log(nearlyEqual(0.1 + 0.2, 0.3)); // true

You can also choose an application-specific tolerance:

function nearlyEqual(a, b) {
  return Math.abs(a - b) < 0.000001;
}

For money or exact decimal values

Avoid floating-point arithmetic for currency. Use integer units instead:

const priceA = 10; // cents
const priceB = 20; // cents

console.log(priceA + priceB === 30); // true

Or use a decimal arithmetic library, such as decimal.js, big.js, or similar.

For display only

If you only need to display the result, round it:

const result = 0.1 + 0.2;

console.log(result.toFixed(2)); // "0.30"

But do not rely on formatting methods like toFixed() for precise internal comparisons.

Server-recorded answer

Model: gpt-5.5-2026-04-23

9.6s · 598 tok · $0.01701

Grok 4.7

Because JavaScript numbers are IEEE 754 binary floating-point, and many decimals (including 0.1 and 0.2) cannot be stored exactly.

0.1 + 0.2 is not the value 0.3. It is a tiny bit larger:

0.1 + 0.2          // 0.30000000000000004
0.1 + 0.2 === 0.3  // false

Binary fractions can only represent sums of powers of 1/2 (0.5, 0.25, 0.125, …). 0.1 and 0.2 need infinite bits in binary, so they are rounded. Adding those rounded values does not land exactly on the rounded value of 0.3, so strict equality fails.

How to compare decimals

1. Epsilon (tolerance) — good for general numeric checks

function nearlyEqual(a, b, epsilon = Number.EPSILON) {
  return Math.abs(a - b) < epsilon;
}

nearlyEqual(0.1 + 0.2, 0.3); // true

Number.EPSILON (~2.22e-16) is the gap between 1 and the next representable number. For values far from 1, scale the tolerance, or use a relative check:

function nearlyEqual(a, b, relTol = 1e-10, absTol = Number.EPSILON) {
  const diff = Math.abs(a - b);
  return diff <= Math.max(absTol, relTol * Math.max(Math.abs(a), Math.abs(b)));
}

2. Round to a fixed number of decimal places — good when you care about display precision (money in cents, UI, etc.)

function round(n, decimals) {
  const f = 10 ** decimals;
  return Math.round((n + Number.EPSILON) * f) / f;
}

round(0.1 + 0.2, 10) === round(0.3, 10); // true

Or compare after rounding:

Math.abs((0.1 + 0.2) - 0.3) < 1e-10

3. Integers (best for money)
Store cents (or the smallest unit) as integers so you never add binary fractions:

(10 + 20) === 30  // true, if values are in cents

4. Decimal library — when you need exact base-10 arithmetic
Use something like decimal.js or big.js if you must add/compare decimal strings exactly (accounting, finance).

What not to do

  • Don’t rely on === for results of decimal arithmetic.
  • Don’t use toFixed() for comparison logic without care: it returns a string, and rounding can still surprise you at the edges.

Summary: the false result is expected binary floating-point error, not a JS bug. Compare with a tolerance, round to a known precision, or use integers / a decimal library when exact decimal behavior matters.

Server-recorded answer

Model: grok-4.7

9.9s · 2,040 tok · $0.007148