Subtracting to float values giving negative zero in javascript

264
November 22, 2016, at 10:09 AM

I was trying simple subtraction of float values in javascript 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

Answer 1

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

Answer 2

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.

Answer 3

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.

READ ALSO
undefined error on accessing json/object from laravel controller to ajax call

undefined error on accessing json/object from laravel controller to ajax call

I am trying to manipulate an object/ json return from the controller in ajax jquery success method. .

321
How to determine which library uses $ sign from console?

How to determine which library uses $ sign from console?

I have handled a project which uses multiple JS libraries, including jQuery. Checked.

234