0

I stumbled across a very very weird behavior while coding an app backend on NodeJS serverless.

When I used a certain number and multiplied it by a hundred it seems to cause an error of the JS engine... I tried it on a simple tag on a basic webpage as well and the error remains the same, it's also the same on react. I tried on different browsers (Chrome 86.0.4240.80, Safari 14.0, Firefox 82.0... I am running on MacOS Catalina 10.15.7 but i also tried on my iphone with IOS 14 and the error persists... It seems global...

const toFixedNumber = (toFixTo = 2, base = 10) => (num) => {
        const pow = Math.pow(base, toFixTo);
        return +(Math.round(num * pow) / pow);
};
// the error occurs when number is between 553.17 and 553.21 
const number = 553.2;
console.log(
  "raw number " + number,
  "rounded number " + toFixedNumber(2)(number),
  "rounded number * 100 " + toFixedNumber(2)(number) * 100,
  "raw number * 100 " + number * 100
);
/*
  Output:
  raw number 553.2 
  rounded number 553.2 
  rounded number * 100 55320.00000000001 
  raw number * 100 55320.00000000001
*/

Does anyone experienced the same issue ? Any idea where it might come from ? Nevertheless it seems like a pretty serious issue

user3491125
  • 366
  • 1
  • 3
  • 13
  • 1
    Is this [Is floating point math broken?](https://stackoverflow.com/q/588004) – VLAZ Oct 21 '20 at 12:22
  • I don't know, I never saw something like this before. I thought it could be because of the float, but if you try with 468.2 It'll work for some reasons. Also there is no decimal specified after the .2 and it seems there is a problem on a short range of numbers only – user3491125 Oct 21 '20 at 12:27
  • 1
    It's not related to the number behind the decimal point, it depends on the *entire number*. Floating point numbers (all of the primitive numbers in JS are such) will hold the value as binary. Changing it up or down can have an impact on the precision as you are losing some bits when you divide that you don't get back after multiplying. Or vice versa. Any number can fall prey to this. It's just how floating point math works for computers in general. JS uses a 64-bit IEEE 754 standard for its numbers, so the behaviour should be the same for any such numbers in any language. – VLAZ Oct 21 '20 at 12:31
  • Maybe you want this. https://stackoverflow.com/questions/16742578/bigdecimal-in-javascript – gillall Oct 21 '20 at 12:34
  • I used toFixedNumber(0)(toFixedNumber(2)(number) * 100) which will do the job perfectly. Thank you all anyway for the explanation. – user3491125 Oct 21 '20 at 12:40

0 Answers0