MikeMcl / decimal.js

An arbitrary-precision Decimal type for JavaScript
http://mikemcl.github.io/decimal.js
MIT License
6.36k stars 480 forks source link

Feature request: Add an eval-like method for evaluating a math expression string #153

Closed KBungei closed 4 years ago

KBungei commented 4 years ago

It would be convinient if there was a way to just pass a math expression as a string that contains numbers and the normal JavaScript operators and have it evaluated to a result

something like:

let result = new Decimal("3+2*(7-4)/6");

my not-so-perfect way around that has been to use regular expressions like this

function prepExprToDeci(exprStr) {
  return "Decimal(" + exprStr.replace('+', ").add(").replace('-', ").minus(").replace('/', ").dividedBy(").replace('**', ").toPower(").replace('*', ").times(") + ")";
}

and I have to break down inner brackets for it to work:

function evalInnerBrs(expr) {
  const innerBrRegExp = /\([\d-\+/*]+\)/;
  expr = expr.replace(/\+\-/g, '-');

  while (innerBrRegExp.test(expr)) {
    let innerBrMatches = expr.match(innerBrRegExp);

    for (let match of innerBrMatches) {
      let exprInMatch = match.replace(/\(/, '').replace(/\)/, '');
      expr = expr.replace(/^\-/g, '0-');
      let evalExprResult = eval(prepExprToDeci(exprInMatch));
      expr = expr.replace(match, evalExprResult);
    }
  }
  expr = expr.replace(/\+\-/g, '-');
  return eval(prepExprToDeci(expr));
}

but sometimes it fails

a model case being "5+7(-65)"

perhaps you can help me improve my work around?

MikeMcl commented 4 years ago

I am not able to help you improve your workaround, but I did make a Decimal.eval method a long time ago but never published it due to the existence of math.js, which uses this library under the hood.

I may publish it soon as a decimal.js extension .

MikeMcl commented 4 years ago

Published.

Thanks for the nudge.