1

I'm new to using javascript and I'm trying to make a function that will calculate the numbers in a string.

But i'm having a problem with getting it to calculate some of the numbers in a string.

And was maybe hoping someone could maybe help me or tell me where i'm going wrong i would really appreciate it.

const toCalculate  = (string) => {
  let calculate = "=" + string.toLowerCase();
  if (
    isFinite(
      calculate.replace(
        /\=|\+|\-|\*|\/|\÷|\%|\(|\)|\,|\ |math.|pow|sqrt|round|floor|ceiling|ceil|pi|π|euler|absolute|abs|exp|logarithm|log|random|rand|rng/g,
        ""
      )
    )
  ) {
    calculate = calculate
      .replace(/ /g, "")
      .replace(/÷/g, "/")
      .replace(/power|pow/g, "Math.pow")
      .replace(/sqrt|squareroot/g, "Math.sqrt")
      .replace(/round/g, "Math.round")
      .replace(/floor/g, "Math.floor")
      .replace(/ceiling|ceil/g, "Math.ceil")
      .replace(/pi|π/g, "Math.PI")
      .replace(/euler/g, "Math.E")
      .replace(/absolute|abs/g, "Math.abs")
      .replace(/exp/g, "Math.exp")
      .replace(/logarithm|log/g, "Math.log")
      .replace(/random|rand|rng/g, "Math.random()");
    if (calculate.replace(/[^%]/g, "").length > 0) {
      for (let i = 0; i < calculate.replace(/[^%]/g, "").length; i++) {
        while (
          (calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "+" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "-" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "*" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "/" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "(" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == ")" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "," ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "^" ||
            calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "x" ||
            getSubstringIndex(calculate, "%", i + 1) + 1 == calculate.length) &&
          calculate.replace(/[^%]/g, "").length > 0
        ) {
          for (let j = getSubstringIndex(calculate, "%", i + 1); j > -1; j--) {
            if (
              calculate[j] == "=" ||
              calculate[j] == "+" ||
              calculate[j] == "-" ||
              calculate[j] == "*" ||
              calculate[j] == "/" ||
              calculate[j] == "(" ||
              calculate[j] == ")" ||
              calculate[j] == "," ||
              calculate[j] == "^" ||
              calculate[j] == "x"
            ) {
              calculate =
                calculate.substring(0, j + 1) +
                calculate.substring(j + 1, getSubstringIndex(calculate, "%", i + 1)) / 100 +
                calculate.substring(getSubstringIndex(calculate, "%", i + 1) + 1, calculate.length);
              break;
            }
          }
        }
      }
    }
    calculate = calculate.replace(/=/g, "");
    if (isFinite(eval(calculate))) return string + ' = ' + eval(calculate);
  }
};


console.log('math 0:', toCalculate('2 ÷ 2 + 1 - 2 + 22'));
console.log('math 1:', toCalculate('2 + 2 - 1'));
console.log('math 2:', toCalculate('4 ÷ 2 + 9'));
console.log('math 3:', toCalculate('888 + 88 + 8 + 8 + 8'));
console.log('math 4:', toCalculate('(7+7) * (7 + (1/7))'));
console.log('math 5:', toCalculate('2 + 2 - 1 = 3 + 2'));
console.log('math 6:', toCalculate('6 - 1 x 0 + 2 ÷ 2'));
console.log('math 7:', toCalculate('6^2 ÷ 2(3) + 4'));
console.log('math 8:', toCalculate('6 - 1 x 0 + 2 ÷ 2'));
console.log('math 9:', toCalculate('6 x 2'));
  • Useful resources: [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173) – VLAZ May 17 '21 at 10:06

1 Answers1

0

I'm not sure how your code works exactly, but I've noticed some issues after debugging.

The first issue is that you forgot to replace the operations x and ^ with there equivalent in javascript, so I added those two line in the beginning :

calculate = calculate.replace(/x/g, "*");
calculate = calculate.replace(/\^/g, "**");

The second issue is that 2(3) means 2x3 for us, but for javascript is means that 2 is a function and 3 in a parameter passed to it, to fix that you need to add * between them, I made a function for that :

function fixMultiplication(exp ,ch){
    for(i=0;i<exp.length;i++){
      if(exp.substring(i,i+1) === ch){
        if (ch === '(' || ch === 'M' ){//before the character
          switch(exp.substring(i-1,i)){
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case 'x':
            case ')':
            case 'π':
              exp=exp.substring(0,i)+"*"+exp.substring(i,exp.length);
          }
        } else {//after the character
          switch(exp.substring(i+1,i+2)){
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case 'x':
            case '(':
            case 'π':
            case 'M':
              exp=exp.substring(0,i+1)+"*"+exp.substring(i+1,exp.length);
          }
        }
      }
    }
    return exp;
  }
  
  
  let string = '6(2)4((3))9';
  console.log("before : "+string);
  string = fixMultiplication(string,"(");
  string = fixMultiplication(string,")");
  console.log("after : "+string);

Now the code looks like this:

const toCalculate  = (string) => {
          function fixMultiplication(exp ,ch){
            for(i=0;i<exp.length;i++){
              if(exp.substring(i,i+1) === ch){
                if (ch === '(' || ch === 'M' ){//before the character
                  switch(exp.substring(i-1,i)){
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                    case 'x':
                    case ')':
                    case 'π':
                      exp=exp.substring(0,i)+"*"+exp.substring(i,exp.length);
                  }
                } else {//after the character
                  switch(exp.substring(i+1,i+2)){
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                    case 'x':
                    case '(':
                    case 'π':
                    case 'M':
                      exp=exp.substring(0,i+1)+"*"+exp.substring(i+1,exp.length);
                  }
                }
              }
            }
            return exp;
          }
          let calculate = "=" + string.toLowerCase();
          calculate = calculate.replace(/x/g, "*");
          calculate = calculate.replace(/\^/g, "**");
          if (
            isFinite(
              calculate.replace(
                /\=|\+|\-|\*|\/|\÷|\%|\(|\)|\,|\ |math.|pow|sqrt|round|floor|ceiling|ceil|pi|π|euler|absolute|abs|exp|logarithm|log|random|rand|rng/g,
                ""
              )
            )
          ) {
            
            calculate = calculate
              .replace(/ /g, "")
              .replace(/÷/g, "/")
              .replace(/power|pow/g, "Math.pow")
              .replace(/sqrt|squareroot/g, "Math.sqrt")
              .replace(/round/g, "Math.round")
              .replace(/floor/g, "Math.floor")
              .replace(/ceiling|ceil/g, "Math.ceil")
              .replace(/pi|π/g, "Math.PI")
              .replace(/euler/g, "Math.E")
              .replace(/absolute|abs/g, "Math.abs")
              .replace(/exp/g, "Math.exp")
              .replace(/logarithm|log/g, "Math.log")
              .replace(/random|rand|rng/g, "Math.random()");
            if (calculate.replace(/[^%]/g, "").length > 0) {
              for (let i = 0; i < calculate.replace(/[^%]/g, "").length; i++) {
                while (
                  (calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "+" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "-" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "*" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "/" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "(" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == ")" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "," ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "^" ||
                    calculate[getSubstringIndex(calculate, "%", i + 1) + 1] == "x" ||
                    getSubstringIndex(calculate, "%", i + 1) + 1 == calculate.length) &&
                  calculate.replace(/[^%]/g, "").length > 0
                ) {
                  for (let j = getSubstringIndex(calculate, "%", i + 1); j > -1; j--) {
                    if (
                      calculate[j] == "=" ||
                      calculate[j] == "+" ||
                      calculate[j] == "-" ||
                      calculate[j] == "*" ||
                      calculate[j] == "/" ||
                      calculate[j] == "(" ||
                      calculate[j] == ")" ||
                      calculate[j] == "," ||
                      calculate[j] == "^" ||
                      calculate[j] == "x"
                    ) {
                      calculate =
                        calculate.substring(0, j + 1) +
                        calculate.substring(j + 1, getSubstringIndex(calculate, "%", i + 1)) / 100 +
                        calculate.substring(getSubstringIndex(calculate, "%", i + 1) + 1, calculate.length);
                      break;
                    }
                  }
                }
              }
            }
            calculate = calculate.replace(/=/g, "");
            calculate = fixMultiplication(calculate,"(");
            calculate = fixMultiplication(calculate,")");
            if (isFinite(eval(calculate))) return string + ' = ' + eval(calculate);
          }
        };
        
        
        console.log('math 0:', toCalculate('2 ÷ 2 + 1 - 2 + 22'));
        console.log('math 1:', toCalculate('2 + 2 - 1'));
        console.log('math 2:', toCalculate('4 ÷ 2 + 9'));
        console.log('math 3:', toCalculate('888 + 88 + 8 + 8 + 8'));
        console.log('math 4:', toCalculate('(7+7) * (7 + (1/7))'));
        console.log('math 5:', toCalculate('2 + 2 - 1 = 3 + 2'));
        console.log('math 6:', toCalculate('6 - 1 x 0 + 2 ÷ 2'));
        console.log('math 7:', toCalculate('6^2 ÷ 2(3) + 4'));
        console.log('math 8:', toCalculate('6 - 1 x 0 + 2 ÷ 2'));
        console.log('math 9:', toCalculate('6 x 2'));

notice that I called fixMultiplication for both ( and )

calculate = fixMultiplication(calculate,"(");
calculate = fixMultiplication(calculate,")");

Notes :

Be careful when using eval() it's a dangerous function with serious security issues.
See Never use eval()!
First dev
  • 495
  • 4
  • 17