This post explains a quiz originally shared as a LinkedIn poll.
🔹 The Question
const prices = [10.5, 20.3, 15.8];
const total = prices.reduce((sum, price) => {
return sum + price;
});
console.log(total);
console.log(typeof total);
Hint: Check what reduce returns when you omit the initial value and the array has only numbers.
🔹 Solution
Correct Answer: B) 46.599999999999994 and number
The output is:
46.599999999999994number
đź§ How this works
JavaScript uses IEEE 754 double-precision floating-point format to represent all numbers. This format cannot precisely represent many decimal fractions, leading to rounding errors during arithmetic operations.
When you add 10.5 + 20.3 + 15.8, the intermediate results accumulate small precision errors:
-
10.5 + 20.3=30.799999999999997(not exactly30.8) -
30.799999999999997 + 15.8=46.599999999999994(not exactly46.6)
This isn't a bug in JavaScript—it's how binary floating-point arithmetic works in virtually all programming languages (Python, Java, C++, etc.). The issue is that decimals like 0.1, 0.2, 0.3 cannot be represented exactly in binary, just like 1/3 cannot be represented exactly in decimal (0.333...).
The type remains number because JavaScript doesn't distinguish between integers and floats—everything is a 64-bit floating-point number.
🔍 Line-by-line explanation
const prices = [10.5, 20.3, 15.8]— creates an array of three floating-point numbers-
prices.reduce((sum, price) => { return sum + price; })— reduces the array:-
First iteration:
sum = 10.5(first element, since no initial value),price = 20.3- Returns:
30.799999999999997(not30.8due to floating-point precision)
- Returns:
-
Second iteration:
sum = 30.799999999999997,price = 15.8- Returns:
46.599999999999994(accumulated error)
- Returns:
-
First iteration:
console.log(total)→46.599999999999994console.log(typeof total)→number
The misleading part: Developers expect 10.5 + 20.3 + 15.8 to equal exactly 46.6 because that's how decimal arithmetic works on paper. But computers use binary representation, and these particular decimals don't have exact binary representations.
🔹 Real-World Impact
Floating-point precision errors cause serious issues in:
- E-commerce: Shopping cart totals that don't match item sum, causing payment gateway rejections or customer complaints
- Financial calculations: Invoice totals, tax calculations, currency conversions showing unexpected pennies
- Analytics dashboards: Metrics that should sum to 100% showing 99.99999999999999% or 100.00000000001%
-
Testing: Assertions like
expect(total).toBe(46.6)failing intermittently -
Data validation: Price comparisons using
===failing when values should be equal
🔹 The Fix
Option 1: Round to fixed decimal places
const total = prices.reduce((sum, price) => sum + price, 0);
const rounded = Math.round(total * 100) / 100;
console.log(rounded); // 46.6
Option 2: Use a decimal library for precision-critical work
import Decimal from 'decimal.js';
const total = prices
.map(p => new Decimal(p))
.reduce((sum, price) => sum.plus(price));
console.log(total.toString()); // "46.6"
Option 3: Format for display
console.log(total.toFixed(2)); // "46.60" (string)
console.log(Number(total.toFixed(2))); // 46.6 (number, rounded)
🔹 Key Takeaways
- JavaScript uses IEEE 754 floating-point arithmetic, which cannot precisely represent many decimal fractions
- Accumulating floating-point operations compounds precision errors
- Never use
===to compare floating-point results; use a tolerance:Math.abs(a - b) < 0.0001 - For financial calculations, work with integers (cents) or use decimal libraries like
decimal.jsorbig.js - Always round or format floating-point numbers before displaying to users
- This behavior is consistent across all IEEE 754-compliant languages, not unique to JavaScript
Top comments (1)
Haha, love this one!! Really shows why JS math can be so sneaky. 10.5 + 20.3 + 15.8 giving 46.599999999999994 is exactly the kind of thing that trips people up. Nice breakdown with the fixes too... rounding, decimal libs, or just formatting makes total sense.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.