I was trying simple subtraction of float values and I got a weird output of negative zero:
var pay = -0.33;
var res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22);
res = res.toFixed(2);
console.log(res);
output: -0.00
I was trying simple subtraction of float values and I got a weird output of negative zero:
var pay = -0.33;
var res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22);
res = res.toFixed(2);
console.log(res);
output: -0.00
Nothing strange here, this is how IEEE floating point works.
Since what you seem to be doing here is formatting a currency value, I would suggest writing a reusable function to do that so it's done consistently throughout your app.
There are several approaches, however which to use depends on the application
It's not a bug. There is nothing wrong with -0 as a value in IEEE floating point: -0 === 0, x + -0 = x, x * -0 = -0 etc. In arithmetic minus 0 works exactly the same way 0 does.
Usually I would handle the -0.00 when formatting, since only -0.00 "looks wierd", -10.20 is just an overdraft :)
res = res.toFixed(2);
if(res === '-0.00'){
res = '0.00';
}
I suggest this article to understand IEEE floating point better: What Every Computer Scientist Should Know About Floating-Point Arithmetic
javascript and machine in total handle with double as almost infinite number.
when rounding to 2 decimal places, javascript gives the nearest rounded number.
to fix it, use:
var pay = -0.33;
var res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22);
res = res.toFixed(2);
return (Math.round(res * 100) / 100);
way better than other's workarounds here will evaluating strings..
EDIT
if you change the round number, better use this:
var fixRound = 2,
pay = -0.33,
rounding = Math.pow(10, fixRound),
res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22);
res = res.toFixed(fixRound );
return (Math.round(res * rounding ) / rounding );
this way, all you need to change in the code in order for it to work with toFixed(3), toFixed(4),toFixed(5) and so on, is just set fixRound
value to be the number you wish.
Here is a solution I found to prevent toFixed to return negative zero:
fixed_toFixed = (value, prec) => Math.abs(value) < Math.pow(10, -prec) ? (0).toFixed(prec) : value.toFixed(prec);
Actually what is happening here is that there is no initial positive number greater than or equal to the negative number. if you want to get a positive value as a result then the positive number should be greater than or equal to the negative number What i am trying to say is : if you do this: -0.33-0.11+0.44 then you will get a positive zero value as there is an initial positive value greater than all the negative numbers.