DEV Community

Cover image for Javascript Interview Question of the Day #8 [Talk::Overflow]
ValPetal Tech Labs
ValPetal Tech Labs

Posted on

Javascript Interview Question of the Day #8 [Talk::Overflow]

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);
Enter fullscreen mode Exit fullscreen mode

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.599999999999994
  • number

đź§  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 exactly 30.8)
  • 30.799999999999997 + 15.8 = 46.599999999999994 (not exactly 46.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

  1. const prices = [10.5, 20.3, 15.8] — creates an array of three floating-point numbers

  2. 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 (not 30.8 due to floating-point precision)
    • Second iteration: sum = 30.799999999999997, price = 15.8
      • Returns: 46.599999999999994 (accumulated error)
  3. console.log(total) → 46.599999999999994

  4. console.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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Option 3: Format for display

console.log(total.toFixed(2)); // "46.60" (string)
console.log(Number(total.toFixed(2))); // 46.6 (number, rounded)
Enter fullscreen mode Exit fullscreen mode

🔹 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.js or big.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)

Collapse
 
martijn_assie_12a2d3b1833 profile image
Martijn Assie

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.