Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting a number with exactly two decimals in JavaScript

I have this line of code which rounds my numbers to two decimal places. But I get numbers like this: 10.8, 2.4, etc. These are not my idea of two decimal places so how I can improve the following?

Math.round(price*Math.pow(10,2))/Math.pow(10,2); 

I want numbers like 10.80, 2.40, etc. Use of jQuery is fine with me.

like image 610
Abs Avatar asked Nov 13 '09 01:11

Abs


People also ask

How do I get 2 decimal places in JavaScript?

Syntax. number. toFixed(2); In the above syntax toFixed() is the method of formatting a number with twoIn the above syntax toFixed() is the method of formatting a number with two decimals in JavaScript and number is the number to be formatted with two decimals.

How do you move a number to 2 decimal places?

Rounding a decimal number to two decimal places is the same as rounding it to the hundredths place, which is the second place to the right of the decimal point. For example, 2.83620364 can be round to two decimal places as 2.84, and 0.7035 can be round to two decimal places as 0.70.

How do you control decimals in JavaScript?

To limit decimal places in JavaScript, use the toFixed() method by specifying the number of decimal places.

How do you round decimal numbers in JavaScript?

The Math. round() method rounds a number to the nearest integer. 2.49 will be rounded down (2), and 2.5 will be rounded up (3).


2 Answers

To format a number using fixed-point notation, you can simply use the toFixed method:

(10.8).toFixed(2); // "10.80"  var num = 2.4; alert(num.toFixed(2)); // "2.40" 

Note that toFixed() returns a string.

IMPORTANT: Note that toFixed does not round 90% of the time, it will return the rounded value, but for many cases, it doesn't work.

For instance:

2.005.toFixed(2) === "2.00"

UPDATE:

Nowadays, you can use the Intl.NumberFormat constructor. It's part of the ECMAScript Internationalization API Specification (ECMA402). It has pretty good browser support, including even IE11, and it is fully supported in Node.js.

const formatter = new Intl.NumberFormat('en-US', {    minimumFractionDigits: 2,          maximumFractionDigits: 2, });  console.log(formatter.format(2.005)); // "2.01" console.log(formatter.format(1.345)); // "1.35"

You can alternatively use the toLocaleString method, which internally will use the Intl API:

const format = (num, decimals) => num.toLocaleString('en-US', {    minimumFractionDigits: 2,          maximumFractionDigits: 2, });   console.log(format(2.005)); // "2.01" console.log(format(1.345)); // "1.35"

This API also provides you a wide variety of options to format, like thousand separators, currency symbols, etc.

like image 155
Christian C. Salvadó Avatar answered Sep 21 '22 09:09

Christian C. Salvadó


This is an old topic but still top-ranked Google results and the solutions offered share the same floating point decimals issue. Here is the (very generic) function I use, thanks to MDN:

function round(value, exp) {   if (typeof exp === 'undefined' || +exp === 0)     return Math.round(value);    value = +value;   exp = +exp;    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))     return NaN;    // Shift   value = value.toString().split('e');   value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));    // Shift back   value = value.toString().split('e');   return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)); } 

As we can see, we don't get these issues:

round(1.275, 2);   // Returns 1.28 round(1.27499, 2); // Returns 1.27 

This genericity also provides some cool stuff:

round(1234.5678, -2);   // Returns 1200 round(1.2345678e+2, 2); // Returns 123.46 round("123.45");        // Returns 123 

Now, to answer the OP's question, one has to type:

round(10.8034, 2).toFixed(2); // Returns "10.80" round(10.8, 2).toFixed(2);    // Returns "10.80" 

Or, for a more concise, less generic function:

function round2Fixed(value) {   value = +value;    if (isNaN(value))     return NaN;    // Shift   value = value.toString().split('e');   value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));    // Shift back   value = value.toString().split('e');   return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2); } 

You can call it with:

round2Fixed(10.8034); // Returns "10.80" round2Fixed(10.8);    // Returns "10.80" 

Various examples and tests (thanks to @t-j-crowder!):

function round(value, exp) {    if (typeof exp === 'undefined' || +exp === 0)      return Math.round(value);      value = +value;    exp = +exp;      if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))      return NaN;      // Shift    value = value.toString().split('e');    value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));      // Shift back    value = value.toString().split('e');    return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));  }  function naive(value, exp) {    if (!exp) {      return Math.round(value);    }    var pow = Math.pow(10, exp);    return Math.round(value * pow) / pow;  }  function test(val, places) {    subtest(val, places);    val = typeof val === "string" ? "-" + val : -val;    subtest(val, places);  }  function subtest(val, places) {    var placesOrZero = places || 0;    var naiveResult = naive(val, places);    var roundResult = round(val, places);    if (placesOrZero >= 0) {      naiveResult = naiveResult.toFixed(placesOrZero);      roundResult = roundResult.toFixed(placesOrZero);    } else {      naiveResult = naiveResult.toString();      roundResult = roundResult.toString();    }    $("<tr>")      .append($("<td>").text(JSON.stringify(val)))      .append($("<td>").text(placesOrZero))      .append($("<td>").text(naiveResult))      .append($("<td>").text(roundResult))      .appendTo("#results");  }  test(0.565, 2);  test(0.575, 2);  test(0.585, 2);  test(1.275, 2);  test(1.27499, 2);  test(1234.5678, -2);  test(1.2345678e+2, 2);  test("123.45");  test(10.8034, 2);  test(10.8, 2);  test(1.005, 2);  test(1.0005, 2);
table {    border-collapse: collapse;  }  table, td, th {    border: 1px solid #ddd;  }  td, th {    padding: 4px;  }  th {    font-weight: normal;    font-family: sans-serif;  }  td {    font-family: monospace;  }
<table>    <thead>      <tr>        <th>Input</th>        <th>Places</th>        <th>Naive</th>        <th>Thorough</th>      </tr>    </thead>    <tbody id="results">    </tbody>  </table>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
like image 42
astorije Avatar answered Sep 20 '22 09:09

astorije