Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding and comparing two decimal numbers in JavaScript

Tags:

javascript

I am trying to add two decimal numbers (arguments could be numbers or strings that are numbers before they are parsed) and compare the outcome with the resultInput. The problem is that the floating-point numbers cannot be represented accurately enough by the system. For example, 0.1 + 0.2 = 0.30000000000000004. So, I am trying to use toFixed() method to format a number using fixed-point notation. I am getting false when I run the code. Not sure where I am getting it wrong. Let me know if you have any ideas.

    function calc(firstNumber, secondNumber, operation, resultInput) {
      let a = parseFloat(firstNumber); //Number()
      let b = parseFloat(secondNumber); //Number()
      let c;
      let d = parseFloat(resultInput);
      console.log(JSON.stringify(`value of d : ${d}`)); //"value of d : NaN"
    
      switch (operation) {
        case '+':
          c = a + b;
          break;
        case '-':
          c = a - b;
          break;
        case '*':
          c = a * b;
          break;
        case '/':
         if (b === 0 && 1 / b === -Infinity) {
           r = Infinity;
         } else {
           r = a / b;
         }
          break;
        default:
          console.log(`Sorry, wrong operator: ${operation}.`);
      }
      console.log(JSON.stringify(`value of c: ${c}`)); // "value of c: 0.30000000000000004"
      let f = +c.toFixed(1);
      let e = +d.toFixed(1);
    
      console.log(JSON.stringify(`value of f: ${f}`)); // "value of f: 0.3"
      console.log(typeof f); //number
      console.log(JSON.stringify(`value of d: ${d}`)); // "value of d: NaN"
      console.log(typeof d); //number
      console.log(JSON.stringify(`value of e: ${e}`)); // "value of e: NaN"
      console.log(typeof e); //number
    
      if (f !== e) return false;
      // if (!Object.is(f, e)) return false;
      return true;
    }
    
    console.log(calc('0.1', '0.2', '+', '0.3'));
like image 999
John John Avatar asked Oct 24 '25 14:10

John John


2 Answers

Rather than converting back and forth to/from strings, you can create a function that tests if two numbers are close enough to be called equal. You decide some small delta and if the numbers are at least that close, you call it good.

function almost(a, b, delta = 0.000001){
    return Math.abs(a - b) < delta
}

// not really equal
console.log("equal?", 0.2 + 0.1 === 0.3)

// but good enough
console.log("close enough?", almost(0.2 + 0.1, 0.3))
like image 69
Mark Avatar answered Oct 27 '25 02:10

Mark


I run your code several times and there is no problem with it. I just found that the '0.3' that you posted, it has an special character that looks like 3 but its not 3. So, when you want to run it on JS it will show an error. So your solution was correct. Check here.

function calc(firstNumber, secondNumber, operation, resultInput) {
  let a = parseFloat(firstNumber);
  let b = parseFloat(secondNumber);
  let aux = parseFloat(resultInput);
  let r;

  switch (operation) {
    case '+':
      r = a + b;
      break;
    case '-':
      r = a - b;
      break;
    case '*':
      r = a * b;
      break;
    case '/':
      if (b !== 0) {
        r = a / b;
      } else {
        r = 0;
      }
      break;
    default:
      console.log(`Sorry, wrong operator: ${operation}.`);
  }

  return (+r.toFixed(1)) === (+aux.toFixed(1));
}

console.log(calc('0.1', '0.2', '+', '0.3'));
like image 45
Teocci Avatar answered Oct 27 '25 03:10

Teocci