Fundamentals 9 min read

Why 0.1 + 0.2 ≠ 0.3 in JavaScript? Understanding Number Precision and Fixes

This article explains why JavaScript’s Number type suffers from floating‑point precision errors, describes the IEEE‑754 double‑precision storage format, clarifies key Number properties, shows why 0.1 + 0.2 is not exactly 0.3, and provides practical code‑based solutions.

QQ Music Frontend Team
QQ Music Frontend Team
QQ Music Frontend Team
Why 0.1 + 0.2 ≠ 0.3 in JavaScript? Understanding Number Precision and Fixes

Most JavaScript developers have encountered floating‑point precision errors, for example console.log(0.1+0.2===0.3) // false. In JavaScript all numbers, both integers and decimals, are represented by the Number type, which follows the IEEE‑754 64‑bit double‑precision format.

Number storage standard

JavaScript Number uses the IEEE‑754 64‑bit double‑precision floating‑point representation. The 64 bits are divided into three fields:

sign: 1 bit

exponent: 11 bits

fraction (mantissa): 52 bits

The exponent range is 0‑2047. When the exponent is 0 or 2047, special meanings apply depending on whether the fraction is zero (see the table). For normal numbers the exponent is stored with a bias of 1023, and the leading mantissa bit is implicit 1. The value of a normal number is:

For subnormal numbers the leading bits are 0 instead of 1 and the bias is 1022, giving the value:

Key Number properties

Understanding the storage format clarifies several important Number properties:

Number.MAX_VALUE – the largest representable number.

Number.MIN_VALUE – the smallest positive subnormal number.

Number.EPSILON – the difference between 1 and the smallest number greater than 1.

Number.MAX_SAFE_INTEGER – the largest integer that can be represented exactly (2^53‑1). Example:

Math.pow(2,54)===Math.pow(2,54)+1 // true

Number.MIN_SAFE_INTEGER – the negative of Number.MAX_SAFE_INTEGER (‑9007199254740991).

Why 0.1 + 0.2 ≠ 0.3

0.1 in binary is 0.0001100110011… (repeating). After rounding to 52 fraction bits the stored value becomes slightly larger. The same occurs for 0.2 and 0.3. Adding the stored binary values of 0.1 and 0.2 yields a binary fraction that rounds to 0.30000000000000004, not exactly 0.3. The following code shows the binary strings and their lengths.

var a = 0.1;
console.log(a.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101
var b = 0.2;
console.log(b.toString(2)); // 0.001100110011001100110011001100110011001100110011001101
var c = 0.3;
console.log(c.toString(2)); // 0.010011001100110011001100110011001100110011001100110011
var d = 0.1 + 0.2;
console.log(d.toString(2)); // 0.0100110011001100110011001100110011001100110011001101
console.log(d.toString(2).length); // 54

The resulting binary sum is rounded to 52 fraction bits, producing the final value 0.01001100…110100, which differs from the binary representation of 0.3.

Floating‑point precision solutions

Depending on the use case, you can mitigate precision loss in several ways:

For display only, use Number.prototype.toFixed together with parseFloat.

function formatNum(num, fixed = 10) {
  return parseFloat(num.toFixed(fixed));
}
var a = 0.1 + 0.2;
console.log(formatNum(a)); // 0.3

For arithmetic, convert operands to integers, perform integer operations, then scale back. Example addition function:

function add(num1, num2) {
  var decimalLen1 = (num1.toString().split('.')[1] || '').length;
  var decimalLen2 = (num2.toString().split('.')[1] || '').length;
  var baseNum = Math.pow(10, Math.max(decimalLen1, decimalLen2));
  return (num1 * baseNum + num2 * baseNum) / baseNum;
}
console.log(add(0.1, 0.2)); // 0.3

Reference material:

https://en.wikipedia.org/wiki/IEEE_754

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

https://en.wikipedia.org/wiki/Normal_number_(computing)

https://en.wikipedia.org/wiki/Denormal_number

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptprecisionfloating-pointcodenumberIEEE-754
QQ Music Frontend Team
Written by

QQ Music Frontend Team

QQ Music Web Frontend Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.