Lodash rounding precision
Asked Answered
P

1

8

I'm trying to display a number as a percent by using _.round and then by multiplying the number by 100. For some reason, when I multiply the rounded number, the precision gets messed up. Here's what it looks like:

var num = 0.056789,
    roundingPrecision = 4,
    roundedNum = _.round(num, roundingPrecision),
    percent = (roundedNum * 100) + '%';

console.log(roundedNum); // 0.0568
console.log(percent); // 5.680000000000001%

fiddle

Why is the 0.000000000000001 added to the number after multiplying by 100?

Plunge answered 1/9, 2015 at 15:55 Comment(3)
#1459133Prescott
Thanks @JamesDonnelly!Plunge
Please provide a succinct answer to your own question, @TimPerkins. The referenced post might cover the subject, but it is unclear how exactly.Olen
O
11

This is due to the fact that numbers are represented internally as binary numbers with limited precision.

See also "Is floating point math broken?"


Is floating point math broken?

0.1 + 0.2 == 0.3 -> false

0.1 + 0.2 -> 0.30000000000000004

Any ideas why this happens?

Which got the answer:

Binary floating point math is like this. In most programming languages, it is based on the IEEE 754 standard. JavaScript uses 64-bit floating point representation, which is the same as Java's double. The crux of the problem is that numbers are represented in this format as a whole number times a power of two; rational numbers (such as 0.1, which is 1/10) whose denominator is not a power of two cannot be exactly represented.


To get the correct outcome in your case, you need to round after all the arithmetic:

var num = 0.056789,
  roundingPrecision = 4,
  roundedNum = _.round(num * 100, roundingPrecision),
  percent = roundedNum + '%';

console.log(percent); // 5.6789%
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
Olen answered 22/7, 2016 at 19:5 Comment(1)
Pedantic, but technically, to get the answer the original question asker wanted, you would need to do roundingPrecision - 2 (with appropriate bounding guards). Otherwise, you've increased the amount of precision desired.Eosin

© 2022 - 2024 — McMap. All rights reserved.