skip to Main Content

I am trying to build a function that can return correct rounding off for both positive and negative values.

Here is my requirement

Input       Output
-1.8550     -1.86
1.8550       1.86
-1384.8540   -1384.85
1384.8540     1384.85
-1384.8550   -1384.86
-1384.8560   -1384.86
-3203.8640   -3203.86 

I tried below, but its not working.!

var customRoundOff = function(value) {
  debugger;
  var valueSign = Math.sign(value);
  var numericalPart = Math.abs(Number((value + "").split(".")[0]));
  var decPart = (value + "").split(".")[1];

  if (decPart && numericalPart) {
    var pntedDecimal = Number('0.' + decPart);
    var roundedDecimal = pntedDecimal.toFixed(2);
    var roundedValue = numericalPart + roundedDecimal;
    
    console.log("pntedDecimal", pntedDecimal);
    console.log("roundedDecimal", roundedDecimal);
    console.log("numericalPart", numericalPart);
    console.log("roundedValue", roundedValue);
    
    return roundedValue * valueSign; // Returns float
  } else {
    return value.toFixed(2); // Returns string
  }
}

customRoundOff(-1.8550);

3

Answers


  1. You mneed to add a small amount to get a rounding for the next digit.

    This is necessay because toFixed rounds with 0.006 to 0.01, instead of 0.005 to 00.1.

    const
        round = n => {
            const sign = Math.sign(n);
            return sign * (Math.abs(n) + 0.000999999999).toFixed(2);
        },
        values = [-1.8550, 1.8550, -1384.8540, 1384.8540, -1384.8550, -1384.8560, -3203.8640];
        
    console.log(...values.map(round));
    Login or Signup to reply.
  2. I now know what is wrong with a simple +n.toFixed(2):

    it returns faulty values for the first two test cases -1.8550 and 1.8550 !!!

    const
        round = n => {
            const sign = Math.sign(n);
            return sign * (Math.abs(n) + 0.000999999999).toFixed(2);
        },
        rnd = n => +n.toFixed(2),
        values = [-1.8550, 1.8550, -1384.8540, 1384.8540, -1384.8550, -1384.8560, -3203.8640];
        
    console.log(JSON.stringify(values.map(round)));  // Nina's solution
    console.log(JSON.stringify(values.map(rnd)));    // mine --> **wrong**

    Wow – interesting point from Nina: the results are indeed wrong – on both
    Chrome and Edge browsers (see her comment!). Ummmpffff – I didn’t expect that!

    So: I’ll eat humble pie and retract my "answer"! 🤷🏾‍♂️

    Login or Signup to reply.
  3. Another alternative is using Intl.NumberFormat if string output is not a problem.

    const arrNumbers=[-1.8550 ,1.8550, -1384.8540, 1384.8540, -1384.8550, 1384.8550, -3203.8640];
    
    for (var i=0 ; i<arrNumbers.length; i++){
        console.log(
          new Intl.NumberFormat('en-US', { maximumFractionDigits: 2 }).format(arrNumbers[i])
        )
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search