Javascript: parseFloat not working

16.5k views Asked by At

I am using jQuery to pull some data from a web page, it comes back as an array with the following values (.5, .25, 1.25, 3.75) which I am trying to add. Here's my code snippet:

var th = 0;
    for (thisrow in objGrid) {
        var hours = objGrid[thisrow]['hours'];
        th = th+parseFloat(hours);
        console.log(hours);

        $("#msgbox").html("Showing records for week: " + thisDate + ". Total Hours for the week : " + th);
   }

in console.log I am getting this for the hours - 0, 0 , 1, 3 and it is totaling 4. If I don't use parseFloat I still get the same results, (thought I would get NaN). What am I doing wrong?

4

There are 4 answers

1
Phrogz On BEST ANSWER

I think you must have some other problem, as what you are describing should work. For example (here's a bad-but-direct translation of your code):

var grid = [ ".5", ".25", "1.25", "3.75" ];
var th = 0;
for (x in grid){
  var h = grid[x];
  var hrs = parseFloat(h);
  th = th + hrs;
  console.log( h, hrs );
}
//   .5 0.5
//  .25 0.25
// 1.25 1.25
// 3.75 3.75

console.log( th );
// 5.75

A few things you should change about your code anyhow:

  1. Don't use for ( x in a ) to iterate over an array; use a numeric for loop: for (var i=0,len=a.length;i<len;++i)

  2. Always var your variables. You're using and overwriting a global thisrow variable. Even when you use for ... in, do it like so for (var x in o) (unless you have declared your variable earlier in the function).

  3. You should use th += ... instead of th = th + ..., just because it's shorter and DRYer.

  4. You should use *1 instead of parseFloat. It's faster, less typing, and doesn't lie to you when you have a janky string.

4
Paul Lysak On

Not sure about this, but try to write var th = 0.0; - maybe, javascript recognizes first integer number and tries to convert second operant to integer. By the way, what browser do you use?

3
user470714 On

The question is: why are your decimal values being rounded. After poking around myself, I found that the for(... in ...) construct itself is rounding the values down. If you access the array element directly, i.e. objGrid[0][i], then the floats will retain their original value, and not be rounded. Hence, my suggestions would be to use a standard for() loop instead of for(in).

EDIT:

For those disbelieving my results, check out this code snippet:

var arr = [.5,.25,1.25, 3.75];

alert(arr[0]);

for(v in arr){
    alert(arr[0]);
    alert(v);
}

This is way simplified version of the OP's question, but same principle. Look at the results of the alert statements. It will be .5, .5, then 0 ... all from how I'm referencing the variable, which is presumably pointing to the same place in memory, but in the later case, rounding the value (apparently).

Tested this myself on the latest version of Firefox.

2
Thevs On
var hours = objGrid[thisrow]['hours']+"";

should do the trick. ParseFloat() takes charaster number's value.