Mathematical account with exact accuracy returns different value in JavaScript [duplicate]

2

I have the following math operation, and the worst thing is, this operation handles monetary values.

3898.95 / 3.0

If you do this operation on the calculator the result will be equal to: 1299,65 exact.

But with JavaScript the result will be equal to: 1299,649999999999 , just put this operation on an alert you will see the result.

And in my application it accepts only 2 decimals after the comma and truncates the rest with the use of a filter in the AngularJS, that is, in an installment it will always be missing a few cents since the result will be 1299,64 .

Filter on AngularJS:

app.filter("currencyRounded",function(){    
    return function(val){
        return truncateDecimals(val, 2);
    }
});

Functions that the filter execution calls:

function truncateDecimals (num, digits) {
    if (num == undefined) num = 0.0;
    var numS = num.toString(),
        decPos = numS.indexOf('.'),
        substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
        trimmedResult = numS.substr(0, substrLength),
        finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    return formatOnlyNumber(parseFloat(finalResult)).replace(/\./g,',');
}

function formatOnlyNumber(valor){
    return parseFloat(Math.round(valor * 100) / 100).toFixed(2);
}

But the main question is, how do you have 1299,65 as a result? If it is just using JavaScript without any other better function yet.

    
asked by anonymous 22.09.2015 / 18:54

2 answers

4

Multiply your value by 100, making your decimal places integer. Round by using Math.round() , eliminating the decimals, and divide the result by 100, retrieving the decimals.

console.log(Math.round(1299.649999999999 * 100) / 100);

You can also choose to use Math.floor() (rounding always down) or Math.ceil() (rounding always up).

    
22.09.2015 / 19:22
0
    Number.prototype.formatMoney = function(c, d, t){
var n = this, 
    c = isNaN(c = Math.abs(c)) ? 2 : c, 
    d = d == undefined ? "." : d, 
    t = t == undefined ? "," : t, 
    s = n < 0 ? "-" : "", 
    i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", 
    j = (j = i.length) > 3 ? j % 3 : 0;
   return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
 };


new Number(3898.95 / 3.0 ).formatMoney(2,',','.');

Although I even marked it as duplicate, but maybe you did not understand how to use the function, so it's up there.

  

link

    
22.09.2015 / 19:04