Math account with exact precision returns different value in Javascript

Asked

Viewed 237 times

2

I have the following mathematical operation, and what’s worse, this operation manipulates 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 that you will see the result.

And in my application only accepts 2 decimal numbers after the comma and truncates the rest with the use of a filter in Angularjs, ie in a installment will always lack a few cents since the result will be 1299,64.

Filter in Angularjs:

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

Functions that 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 to have 1299,65 as a result? If you are only using Javascript without any other better function yet.

2 answers

4


Multiply its value by 100, making its decimals into integers. Round using the Math.round(), eliminating the decimals, and divide the result by 100, recovering the decimals.

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

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

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,',','.');

Even though I marked it as duplicate myself, but maybe you didn’t understand how to use the function, so ta ai.

/a/11267/12032

  • Thanks for your reply, in this case returns as String and including the colons and commas together, but the function performs calculations and it will be very useful to use what you passed when the result will be displayed on the screen.

  • The function demonstrated in the question returns numerical values. There is no need to manipulate string when there are mathematical methods that meet this need.

  • @Mfedatto passed an example because of the mile and decimal masks(English is with comma and not dot) you treated only rounding, at this point you are right in using only native functions.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.