Skip to content

A mathematical expression parser for Javascript.

License

Notifications You must be signed in to change notification settings

prianyu/calculator

Repository files navigation

中文文档

calculator

A mathematical expression parser for Javascript.

  • Works in Wechat miniProgram
  • Supports IE9+
  • Supports AMD/CommonJS
  • Supports custom operators
  • Supports custom functions

You can use the util to parse a mathematical expression into an Reverse Polish Notation or evaluate it.For example,when you parse 1+2*3,you will get the expression + * 3 2 1 and the result 7.

Installation

Direct download

Download the script here and include it:

<script src="/dist/calculator.min.js"></script>
<!-- or -->
<script src="/dist/calculator.js"></script>

Package Managers

NPM

$ npm install @iboxer/calculator --save

AMD

require(['./dist/calculator.js'], function(Calculator) {
  var calculator = new Calculator()
  calculator.parse("1+2+3")
})

Basic Usage

Instance

new Calculator(options)

var calculator = new Calculator();

options

handleError[Function]: Error handler.For more details, please click hereclick here operators[Array|Object]: Custom operators.For more details, please click hereclick here precision[Boolean]: Whether to deal with floating point number precision, default true cache[Boolean]: Whether to open the calculation cache,it is "true" by default. If the calculation results of the same expression have different results according to different conditions, you should set it to "false", such as trigonometric functions of radian and angle

var c1 = new Calculator({
  precision: false
})
c1.parse("0.1+0.2").value //0.30000000000000004
c1.parse("1.2/6").value //0.19999999999999998

var c2 = new Calculator()
c2.parse("0.1+0.2").value //0.3
c2.parse("1.2/6").value //0.2

Parse

var result = calculator.parse("1+2*3");
console.log(result);

You will get the result:

  • value: The result of evaluating the expression
  • notation: The Reverse Polish Notation of parsing the expression

So you can get the result by result.value and get the notation by result.notation.

The util supports parsing mathematical operator(like +,-,*,/) and functions,Currently it supports by default the following mathematical operators:

Operator Type Precedence Description
+ prefix 3 positive sign
- prefix 3 negative sign
+ infix 2 addition
- infix 2 subtraction
* infix 4 multiplication
/ infix 4 division
| infix 4 Mod
% postfix 6 percentage
(,) prefix,postfix 0 parentheses
! postfix 6 factorial
^ infix 4 exponentiation
// infix 4 radical expression
log func 0 logarithm
abs func 0 get absolute value
sin,tan,cos func 0 trigonometric function
, infix 1 parameter separator of a function

API

You can also define custom operators and functions by using the API definedOperators(Object|Array).For example, you may define an operator || to get the quotient and an function ca to get the area of a circle:

calculator.definedOperators({
  token: "||",
  type: "infix",
  func: function(a, b) {
    return Math.floor(a / b);
  },
  weight: 4
});
calculator.definedOperators({
  token: "ca",
  type: "func",
  func: function(r) {
    return Math.PI * r * r;
  }
});

console.log("ca(5) = ", calculator.parse('ca(5)').value); // ca(5) =  78.53981633974483
console.log("10 || 3 + 2 = ", calculator.parse('10 || 3 + 2').value); // 10 || 3 + 2 = 5
Param Type Required Description
token String Yes name of the operator,can not be(, )or,
func Function Yes the handle function
type String No type of the operator,just can be prefix,'infix',postfix and func,default func
weight Number No the precedence of the operator,default 0
rtol Boolean No is it a right-combination operator?,default undefined

The same operator can be infix and prefix ,like the operator +,but infix and postfix should be mutually exclusive The API can pass in an object or an array of objects to define a set of operators at the same time You can overload the behavior of all operators, except(, )and,. For example, You may want trigonometric functions to support both radian and angle:

var isAngle = false
calculator.definedOperators({
  token: "sin",
  func: function(a) {
    a = isAngle ? calculator._rectify(a, calculator._rectify(Math.PI, 180, "/"), "*") : a
    return Math.sin(a)
  }
});

_rectify is a private method, which is used to deal with floating point number precision. If necessary, you can use it: _rectify (a, b, operator)

Errors

When parse a invalid expression, you will get an error.In order to customize error handling, exceptions will not be thrown directly.Instead,you will get the result like:

{
  code: 1004,
  message: "Opening parenthesis is more than closing parenthesis",
  pos: 20,
  token: "/"
}
key description
code error code
message description
pos the error position in the expression
token current operator
and get a warning on console like:

![](./images/error.png)

By default, the error object is returned as a result, and you can define a custom error-handler by passing  `handleError` for the instance:

```javascript
var calculator = new Calculator({
  handleError: function(err) {
    if(err.code === 1006)
      return {
        value: Infinity
      }
  }
});

Here are all the error types:

| code | description|
|:----:|--------|
|1001|Contains undefined operators|
|1002|Syntax error|
|1003|Missing a opening parenthesis after a function|
|1004|Opening parenthesis is more than closing parenthesis|
|1005|Closing parenthesis is more than opening parenthesis|
|1006|The divisor cannot be zero|
|1007|The base number of logarithmic operations must be greater than 0 and not equal to 1|
|1008|The factorial base must be a non-negative integer|


## Demos

[Demos](./test/index.html)

About

A mathematical expression parser for Javascript.

Resources

License

Stars

Watchers

Forks

Packages

No packages published