Legion
Legion

Reputation: 129

How to manage numbers with x.999999 decimal places

I'm facing the next problem. I am performing mathematical operations to calculate weights where I am using a function to return only 2 decimal places but sometimes the result is not as expected. Here is an example

I have a paper that weighs 49.8 and I want to subtract 1/4, that is 12.45 and do it 4 times but when I do this subtraction 49.8 - 12.45 the result gives me 37.34999999999999999999994 when in fact it should be 37.35 because if I do the whole process with my function the result would not be 0, it would be as follows

So that's the problem because 49.8/4 = 12.45 but the way I'm doing it is not possible

How can I solve this, a way where if the third decimal place of the number is 9 round it and return it with only 2 decimals otherwise use my function to return it with 2 decimals

My function:

function threeDecimals(num) {
  const multipliedNum = num * 100;
  const truncatedNum = Math.trunc(multipliedNum);
  const num3decimals = truncatedNum / 100;
  return num3decimals;
}

Upvotes: 0

Views: 800

Answers (2)

Evert
Evert

Reputation: 99728

Floating point numbers have this property by design. If you need to have base-10 precision, it's not enough to add a few decimals and round, because errors can still slip in in higher precisions.

You will need to use a third party library that guarantees base10 accuracy for the examples you gave.

Note that nothing will give you accuracy for every type of operation. Even Decimal.js will round 1/3 and not have a perfect representation, just like floating point numbers give seemingly 'incorrect' outcomes.

Upvotes: 1

gog
gog

Reputation: 11347

If you need exact calculations, operate on smaller units (milligrams instead of grams), so that intermediate values are always integers:

weight = 49800
f = (weight / 4) | 0


weight -= f
weight -= f
weight -= f

result = weight / 1000

console.log(result)

Upvotes: 0

Related Questions