JavaScript math, round to two decimal places

JavascriptMath

Javascript Problem Overview


I have the following JavaScript syntax:

var discount = Math.round(100 - (price / listprice) * 100);

This rounds up to the whole number. How can I return the result with two decimal places?

Javascript Solutions


Solution 1 - Javascript

NOTE - See Edit 4 if 3 digit precision is important

var discount = (price / listprice).toFixed(2);

toFixed will round up or down for you depending on the values beyond 2 decimals.

Example: http://jsfiddle.net/calder12/tv9HY/

Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Edit - As mentioned by others this converts the result to a string. To avoid this:

var discount = +((price / listprice).toFixed(2));

Edit 2- As also mentioned in the comments this function fails in some precision, in the case of 1.005 for example it will return 1.00 instead of 1.01. If accuracy to this degree is important I've found this answer: https://stackoverflow.com/a/32605063/1726511 Which seems to work well with all the tests I've tried.

There is one minor modification required though, the function in the answer linked above returns whole numbers when it rounds to one, so for example 99.004 will return 99 instead of 99.00 which isn't ideal for displaying prices.

Edit 3 - Seems having the toFixed on the actual return was STILL screwing up some numbers, this final edit appears to work. Geez so many reworks!

var discount = roundTo((price / listprice), 2);

function roundTo(n, digits) {
  if (digits === undefined) {
    digits = 0;
  }

  var multiplicator = Math.pow(10, digits);
  n = parseFloat((n * multiplicator).toFixed(11));
  var test =(Math.round(n) / multiplicator);
  return +(test.toFixed(digits));
}

See Fiddle example here: https://jsfiddle.net/calder12/3Lbhfy5s/

Edit 4 - You guys are killing me. Edit 3 fails on negative numbers, without digging into why it's just easier to deal with turning a negative number positive before doing the rounding, then turning it back before returning the result.

function roundTo(n, digits) {
    var negative = false;
    if (digits === undefined) {
        digits = 0;
    }
    if (n < 0) {
        negative = true;
        n = n * -1;
    }
    var multiplicator = Math.pow(10, digits);
    n = parseFloat((n * multiplicator).toFixed(11));
    n = (Math.round(n) / multiplicator).toFixed(digits);
    if (negative) {
        n = (n * -1).toFixed(digits);
    }
    return n;
}

Fiddle: https://jsfiddle.net/3Lbhfy5s/79/

Solution 2 - Javascript

If you use a unary plus to convert a string to a number as documented on MDN.

For example:+discount.toFixed(2)

Solution 3 - Javascript

The functions Math.round() and .toFixed() is meant to round to the nearest integer. You'll get incorrect results when dealing with decimals and using the "multiply and divide" method for Math.round() or parameter for .toFixed(). For example, if you try to round 1.005 using Math.round(1.005 * 100) / 100 then you'll get the result of 1, and 1.00 using .toFixed(2) instead of getting the correct answer of 1.01.

You can use following to solve this issue:

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2');

Add .toFixed(2) to get the two decimal places you wanted.

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2').toFixed(2);

You could make a function that will handle the rounding for you:

function round(value, decimals) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

Example: https://jsfiddle.net/k5tpq3pd/36/

Alternativ

You can add a round function to Number using prototype. I would not suggest adding .toFixed() here as it would return a string instead of number.

Number.prototype.round = function(decimals) {
    return Number((Math.round(this + "e" + decimals)  + "e-" + decimals));
}

and use it like this:

var numberToRound = 100 - (price / listprice) * 100;
numberToRound.round(2);
numberToRound.round(2).toFixed(2); //Converts it to string with two decimals

Example https://jsfiddle.net/k5tpq3pd/35/

Source: http://www.jacklmoore.com/notes/rounding-in-javascript/

Solution 4 - Javascript

To get the result with two decimals, you can do like this :

var discount = Math.round((100 - (price / listprice) * 100) * 100) / 100;

The value to be rounded is multiplied by 100 to keep the first two digits, then we divide by 100 to get the actual result.

Solution 5 - Javascript

The best and simple solution I found is

function round(value, decimals) {
 return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}   
round(1.005, 2); // 1.01

Solution 6 - Javascript

try using discount.toFixed(2);

Solution 7 - Javascript

I think the best way I've seen it done is multiplying by 10 to the power of the number of digits, then doing a Math.round, then finally dividing by 10 to the power of digits. Here is a simple function I use in typescript:

function roundToXDigits(value: number, digits: number) {
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

Or plain javascript:

function roundToXDigits(value, digits) {
    if(!digits){
        digits = 2;
    }
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

Solution 8 - Javascript

A small variation on the accepted answer. toFixed(2) returns a string, and you will always get two decimal places. These might be zeros. If you would like to suppress final zero(s), simply do this:

var discount = + ((price / listprice).toFixed(2));

Edited: I've just discovered what seems to be a bug in Firefox 35.0.1, which means that the above may give NaN with some values.
I've changed my code to

var discount = Math.round(price / listprice * 100) / 100;

This gives a number with up to two decimal places. If you wanted three, you would multiply and divide by 1000, and so on.
The OP wants two decimal places always, but if toFixed() is broken in Firefox it needs fixing first.
See <https://bugzilla.mozilla.org/show_bug.cgi?id=1134388>

Solution 9 - Javascript

Fastest Way - faster than toFixed():

TWO DECIMALS

x      = .123456
result = Math.round(x * 100) / 100  // result .12

THREE DECIMALS

x      = .123456
result = Math.round(x * 1000) / 1000      // result .123


Solution 10 - Javascript

function round(num,dec)
{
    num = Math.round(num+'e'+dec)
    return Number(num+'e-'+dec)
}
//Round to a decimal of your choosing:
round(1.3453,2)

Solution 11 - Javascript

Here is a working example

var value=200.2365455;
result=Math.round(value*100)/100    //result will be 200.24

Solution 12 - Javascript

To handle rounding to any number of decimal places, a function with 2 lines of code will suffice for most needs. Here's some sample code to play with.



var testNum = 134.9567654;
var decPl = 2;
var testRes = roundDec(testNum,decPl);	
alert (testNum + ' rounded to ' + decPl + ' decimal places is ' + testRes);

function roundDec(nbr,dec_places){
	var mult = Math.pow(10,dec_places);
	return Math.round(nbr * mult) / mult;
}


Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSmudgerView Question on Stackoverflow
Solution 1 - JavascriptRick CalderView Answer on Stackoverflow
Solution 2 - JavascriptJohn GietzenView Answer on Stackoverflow
Solution 3 - JavascriptArne H. BitubekkView Answer on Stackoverflow
Solution 4 - JavascriptCattodeView Answer on Stackoverflow
Solution 5 - JavascriptNaga Srinu KapusettiView Answer on Stackoverflow
Solution 6 - JavascriptHarishView Answer on Stackoverflow
Solution 7 - JavascriptBryceView Answer on Stackoverflow
Solution 8 - JavascriptHalfTitleView Answer on Stackoverflow
Solution 9 - JavascriptKamy DView Answer on Stackoverflow
Solution 10 - JavascriptChris MartinView Answer on Stackoverflow
Solution 11 - JavascriptRodgers KilonzoView Answer on Stackoverflow
Solution 12 - Javascriptuser3232196View Answer on Stackoverflow