0

I have a js file which calculate all totals when a user click, this will sum up all clicked rows but if the number contains decimal, would not add correctly, instead always put 00 on decimals

function calculateRevenue(){
        var sum = 0;
        $("input#check_count_revenue[type=checkbox]:checked").each(function() {
            sum += parseInt($(this).attr("data-revenuecount"));
        });

        $("#revenue_count_totals").html(sum.toFixed(2)).digits();
    };

Then calling the function like this

table.on("change","input#check_count_revenue", function() {
        $(this).closest("td").addClass("checked_revenue");
        calculateRevenue();
        if ($(this).prop("checked") === false)   
        $(this).closest("td").removeClass("checked_revenue");
    });

If the row contains the following

 12.00
 13.00

That would correctly sum 25.00

But

 12.00
 13.01

Still got 25.00 instead of 25.01

Any ideas? I already tried parseFloat in place of parseInt, does not resolve

Danielle Rose Mabunga
  • 1,676
  • 4
  • 25
  • 48
  • 2
    Well obviously `parseInt()` isn't going to work, because it discards decimal places *on purpose*... Once you fix that, you might want to read about floating point maths [in general](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) and [in JS](http://stackoverflow.com/questions/10473994/javascript-adding-decimal-numbers-issue?noredirect=1&lq=1). – nnnnnn Nov 02 '16 at 01:23
  • I edited my Question @PHPglue – Danielle Rose Mabunga Nov 02 '16 at 01:25
  • 2
    What is the `digits()` function that you use there? – Dekel Nov 02 '16 at 01:26
  • You do know that `.toFixed()` will round to the decimal place, right? – StackSlave Nov 02 '16 at 01:27
  • It could be the JavaScript floating point issue, if the rounding is not the problem. To overcome this try multiplying every number by 10 before your mathematical operations then divide by the multiples of 10 to get the number you desire. – StackSlave Nov 02 '16 at 01:31
  • @Dekel digits() function just add comma every three decimal places, removing it wil not resolve the issue – Danielle Rose Mabunga Nov 02 '16 at 01:35
  • Did you try to remove **both** the `digits()` **and** the `parseInt()` from your code? – Dekel Nov 02 '16 at 01:36
  • Similar to @Dekel's comment, remove `digits()` and replace `parseInt()` with `parseFloat()` – K Scandrett Nov 02 '16 at 01:42
  • The math works in FIreFox, but without, `.toFixed()` I get `25.009999999999998`. – StackSlave Nov 02 '16 at 01:42
  • You say that removing `digits()` won't resolve the issue. If it contains `parseInt()` then removing it will likely give the correct answer. Have you tested without it (also changing `parseInt()` to `parseFloat()` in the above code)? – K Scandrett Nov 02 '16 at 02:07

3 Answers3

-1

This is a common problem not only in JavaScript but several programming languages dealing with floating-point arithmetic.

Check this answer from StackOverflow, this explanation about how they work in JS, and this CS docs for more information about it.

I think is important you understand the problem before giving you any "solution", but if you really need a serious and dependable tool to work with floating point values I recommend you to use math.js.

Community
  • 1
  • 1
David Gomez
  • 2,762
  • 2
  • 18
  • 28
  • I really don't think it's related. Run `(parseFloat('12.01')+parseFloat('13.00')).toFixed(2)` in your console, you will get 25.01. This it not the issue here... – Dekel Nov 02 '16 at 01:35
  • It is the issue, you are just dealing with it using `parseFloat` – David Gomez Nov 02 '16 at 01:36
  • 1
    The question is regarding the usage of parseFloat... check again. – Dekel Nov 02 '16 at 01:37
  • I get what you are saying and you are right, the way you are doing it is the way to deal with the floating-point arithmetic problem, but it doesn't make it go away. – David Gomez Nov 02 '16 at 01:41
  • This is because this is **not** the same problem. – Dekel Nov 02 '16 at 01:42
  • Explain what is happening and why when `parseFloat(12.01) + parseFloat(13.00)` returns `25.009999999999998`. We all want to learn. – David Gomez Nov 02 '16 at 01:44
  • This is not your original question, and the answer to this specific question in the comment already exists in this answer (by dave gomez). But what you are saying is that in **your** code, when you do `parseFloat(12.01) + parseFloat(13.00)` you get `25.00`, and this **makes no sense**, so I guess something in your code is wrong, or you didn't post all of your code. – Dekel Nov 02 '16 at 01:46
  • 1
    @DaveGomez the OP uses `.toFixed(2)` to address this problem – K Scandrett Nov 02 '16 at 01:49
  • That's what I'm saying – David Gomez Nov 02 '16 at 01:51
-1

you can use toFixed() method

var num = 5.56789;
var n = num.toFixed(2);

http://www.w3schools.com/jsref/jsref_tofixed.asp

-2

See if this will work for you:

function sumFix(){
  var a = [].slice.call(arguments), d = a.pop(), s = 0, p = Math.pow(10, d);
  for(var i=0,l=a.length; i<l; i++){
    s += a[i]*p;
  }
  return (s/p).toFixed(d);
}

Then you could do:

function calculateRevenue(){
  var nums = [];
  $('input#check_count_revenue[type=checkbox]:checked').each(function(){
    nums.push(parseFloat($(this).attr("data-revenuecount")));
  });
  $('#revenue_count_totals').html(sumFix.apply(null, nums.concat(2));
};

sumFix takes any number of arguments, the last one being the decimal places you need.

Normal usage without using .apply():

console.log(sumFix(12.00, 13.01, 2));
StackSlave
  • 10,613
  • 2
  • 18
  • 35