skip to Main Content

Is there a way to proper round the number 35.855 to have two decimals in javascript? Trying to round it has different solutions based on the environment (35.85 in Chrome, 35.86 in IE9).

I was looking for a solution at which javascript does wrong rounding for the decimals (rounding .5 values down instead up) and haven’t found a solution that covered all the values that I had. They behaved other in different environments / browsers.

console.log(Math.round(35.855*100)/100);
// result: 35.85 (IE9 : 35.86, Chrome: 35.85 ???)
console.log((35.855).toFixed(2));
// result: 35.85

2

Answers


  1. Chosen as BEST ANSWER

    My solution is just to add the same digit at the end of the number (if there are more than 1 digit), in order to force the previous number to round properly.

    function roundToTwoDecimal(myNumber){
        let myStrNumber = myNumber.toString();
        // checking our number has decimals and if enough decimal points are present 
        if(myStrNumber.split(".").length > 1 && myStrNumber.split(".")[1].length > 2){
            // doubling the last decimal e.g. 35.855 is now = 35.8555 and parsing back to float  
            myStrNumber += myStrNumber.substring(myStrNumber.length-1);
            myNumber = parseFloat(myStrNumber);
        } // no additional decimal needed here.
        // returning the myNumber*100 = 3585.55 ---round--> 3586 / 100 = 35.86 
        return Math.round(myNumber*100)/100;
    }
    

  2. Make rounding of 1 character after the decimal part:

    const round = (num, digits = 2) => {
      const str = num.toString(), idx = str.indexOf('.');
      if (idx < 0) {
        return num;
      }
      const left = str[idx + 1 + digits]; // round this char
      return left ? parseFloat(str.slice(0, idx + 1 + digits)) + (left >= 5) * (str[0] === '-' ? -1 : 1) / 10 ** digits : num;
    }
    console.log(round(35.855));
    console.log(round(35.8549999));
    console.log(round(-35.8549999, 3));
    console.log(round(35.85));
    console.log(round(35.8));
    console.log(round(35));

    And a benchmark:

    ![![enter image description here

    <script benchmark data-count="1000000">
    
    // @benchmark Alexander slice
    const round = (num, digits = 2) => {
      const str = num.toString();
      const idx = str.indexOf('.');
      if(idx < 0){
        return num;
      }
      const left = str[idx + 1 + digits];
      return left ? parseFloat(str.slice(0, idx + 1 + digits)) +(left >= 5) * (str[0] === '-' ? -1 : 1)/ 10 ** digits : num;
    }
    // @run
    
    round(35.855);
    round(35.8549999);
    round(35.8549999, 3);
    round(35.85);
    round(35.8);
    round(35);
    
    // @benchmark Sercan Samet Savran
    
    function roundToTwoDecimal(myNumber){
        let myStrNumber = myNumber.toString();
        // checking our number has decimals and if enough decimal points are present 
        if(myStrNumber.split(".").length > 1 && myStrNumber.split(".")[1].length > 2){
            // doubling the last decimal e.g. 35.855 is now = 35.8555 and parsing back to float  
            myStrNumber += myStrNumber.substring(myStrNumber.length-1);
            myNumber = parseFloat(myStrNumber);
        } // no additional decimal needed here.
        // returning the myNumber*100 = 3585.55 ---round--> 3586 / 100 = 35.86 
        return Math.round(myNumber*100)/100;
    }
    
    // @run
    
    roundToTwoDecimal(35.855);
    roundToTwoDecimal(35.8549999);
    roundToTwoDecimal(35.8549999, 3);
    roundToTwoDecimal(35.85);
    roundToTwoDecimal(35.8);
    roundToTwoDecimal(35);
    
    
    </script>
    <script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search