Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

string-math

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

string-math - npm Package Compare versions

Comparing version 1.0.0 to 1.2.1

2

package.json
{
"name": "string-math",
"version": "1.0.0",
"version": "1.2.1",
"description": "Evaluates the result of the String arithmetical expression",

@@ -5,0 +5,0 @@ "main": "string-math.js",

@@ -5,3 +5,3 @@ # Description

* It **does not use** `eval()`
* It uses regular expressions to parse [String] equations
* It uses regular expressions to parse [String] formulas `"2+2"` into [Number] formulas `2+2`. Then it is performed as the common JavaScript arithmetic operation.

@@ -13,6 +13,7 @@ ```javascript

"3.5+5*(-4-(3/(3+1)-12*3-.2*22)-16/4*12-5/(2)+3.5+2.5*(1.5-2*7))-16" //-225.5
".25e+2*10" //250
```
* Any bugs found? Give me to know on [GitHub](https://github.com/devrafalko/string-math)
* Also check out [**`exact-math`**](https://www.npmjs.com/package/exact-math) to compute arithmetical formulas with precise floating point values; *(get rid of `0.30000000000000004` values)*
* If you need to perform arithmetic formulas with the **floating point precision** *(avoid `0.30000000000000004` return values)* or to perform arithmetic formulas with **big numbers**, check out [**`exact-math`**](https://www.npmjs.com/package/exact-math) package. It implements `string-math` features as the `exactMath.formula` method.

@@ -65,3 +66,3 @@

### `stringMath(expression)`
### `stringMath(expression[,callback])`
##### `expression` **[String]**

@@ -73,2 +74,3 @@ * the arithmetical formula

* `-5`, `-.4`, `-5.55` negative values
* `2e-2`, `.25e+12`, `-3e-10` exponential notation values
* `*` multiplication sign

@@ -80,2 +82,16 @@ * `/` division sign

##### `callback` **[Function]** *(optional)* *(synchronous)*
* by default, if the `callback` argument **is omitted** and the `expression` is of incorrect type or is invalid, the `Error` object is **`thrown`**. If the `callback` is defined, the `Error` object is passed through the `callback` function, rather than being **`thrown`**.
* if the [Function] `callback` argument is defined, it is called with the following arguments:
* [0] `error`
It equals `null`, if the `expression` is of correct type and is valid math formula.
Otherwise it equals `Error` object.
* [1] `result`
It equals `null` if the `expression` is of incorrect type or if the math formula is invalid.
Otherwise it equals [Number] result.
# Return
If the math formula is of correct type and is valid, it returns the [Number] result. Otherwise it returns `null`.
# Tips

@@ -100,5 +116,7 @@ * the arithmetic **order of operations** is respected:

* ` -.1 - -5`
* `2 + 3e-5`
* `.25e+5 * -.25e-5`
* the spaces are **not allowed** between:
* negative sign and value: `-2 - - 2`
* period and digit in decimal fraction: `5 + . 3`
* uneven opening and closing brackets: `5 + (3 * (3 + 4)`
* exponential notation formula: `.2 e-5`, `2e - 5`, `3e +10`

@@ -1,20 +0,20 @@

function stringMath(eq){
if(typeof eq !== 'string') throw TypeError('The [String] argument is expected.');
const mulDiv = /(-?\d*\.?\d+)\s*([*/])\s*([+-]?\d*\.?\d+)/;
const plusMin = /([+-]?\d*\.?\d+)\s*([+-])\s*([+-]?\d*\.?\d+)/;
function stringMath(eq, callback) {
if (typeof eq !== 'string') return handleCallback(new TypeError('The [String] argument is expected.'), null);
const mulDiv = /([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*([*/])\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)/;
const plusMin = /([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*([+-])\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)/;
const parentheses = /(\d)?\s*\(([^()]*)\)\s*/;
var current;
while(eq.search(/^\s*([+-]?\d*\.?\d+)\s*$/)===-1){
while (eq.search(/^\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*$/) === -1) {
eq = fParentheses(eq);
if(eq===current) throw new SyntaxError('The equation is invalid.');
if (eq === current) return handleCallback(new SyntaxError('The equation is invalid.'), null);
current = eq;
}
return +eq;
return handleCallback(null, +eq);
function fParentheses(eq){
while(eq.search(parentheses)!==-1){
eq = eq.replace(parentheses,function(a,b,c){
function fParentheses(eq) {
while (eq.search(parentheses) !== -1) {
eq = eq.replace(parentheses, function (a, b, c) {
c = fMulDiv(c);
c = fPlusMin(c);
return typeof b==='string' ? `${b}*${c}`:c;
return typeof b === 'string' ? b + '*' + c : c;
});

@@ -27,7 +27,8 @@ }

function fMulDiv(eq){
while(eq.search(mulDiv)!==-1){
eq = eq.replace(mulDiv,function(a){
function fMulDiv(eq) {
while (eq.search(mulDiv) !== -1) {
eq = eq.replace(mulDiv, function (a) {
const sides = mulDiv.exec(a);
return sides[2]==='*' ? sides[1] * sides[3]:sides[1]/sides[3];
const result = sides[2] === '*' ? sides[1] * sides[3] : sides[1] / sides[3];
return result >= 0 ? '+' + result : result;
});

@@ -38,8 +39,8 @@ }

function fPlusMin(eq){
eq = eq.replace(/([+-])([+-])(\d|\.)/g,function(a,b,c,d){return `${b===c ? '+':'-'}${d}`;});
while(eq.search(plusMin)!==-1){
eq = eq.replace(plusMin,function(a){
function fPlusMin(eq) {
eq = eq.replace(/([+-])([+-])(\d|\.)/g, function (a, b, c, d) { return (b === c ? '+' : '-') + d; });
while (eq.search(plusMin) !== -1) {
eq = eq.replace(plusMin, function (a) {
const sides = plusMin.exec(a);
return sides[2]==='+' ? +sides[1] + +sides[3]:sides[1]-sides[3];
return sides[2] === '+' ? +sides[1] + +sides[3] : sides[1] - sides[3];
});

@@ -50,2 +51,12 @@ }

function handleCallback(errObject, result) {
if (typeof callback !== 'function') {
if (errObject !== null) throw errObject;
} else {
callback(errObject, result);
}
return result;
}
}

@@ -52,0 +63,0 @@

@@ -38,2 +38,38 @@ /* global expect */

describe("When the module is executed with incorrect [non-String] first argument and [Function] second argument",function(){
beforeEach(function(){
this.callback = jasmine.createSpy('callback');
this.types = [
1,
true,
null,
{},
[],
/hello/,
()=>{}
];
this.stringMath = stringMath;
});
it('it should not throw an error',function(){
for(var type of this.types){
expect(this.stringMath.bind(this,type,function(){})).not.toThrowError();
}
});
it('it should call this function with error object as the first argument and result value equal to null as the second argument',function(){
for(var type of this.types){
expect(this.stringMath.bind(this,type,this.callback)).not.toThrowError();
expect(this.callback).toHaveBeenCalled();
expect(this.callback).toHaveBeenCalledWith(jasmine.any(Error), null);
}
});
it('it should return null',function(){
for(var type of this.types){
expect(this.stringMath(type,function(){})).toEqual(null);
}
});
});
describe("When the module is executed with correct [String] argument",function(){

@@ -49,2 +85,24 @@ beforeEach(function(){

describe("When the module is executed with correct [String] first argument and [Function] second argument",function(){
beforeEach(function(){
this.callback = jasmine.createSpy('callback');
this.stringMath = stringMath;
});
it('it should not throw an error',function(){
expect(this.stringMath.bind(this,'2+2',function(){})).not.toThrowError();
});
it('it should call this function with null as the first argument and [Number] result value as the second argument',function(){
expect(this.stringMath.bind(this,'2+2',this.callback)).not.toThrowError();
expect(this.callback).toHaveBeenCalled();
expect(this.callback).toHaveBeenCalledWith(null,jasmine.any(Number));
});
it('it should return [Number] value',function(){
expect(this.stringMath('2+2',function(){})).toEqual(jasmine.any(Number));
});
});
describe("When the module is executed with correct [String] argument but incorrect arithmetical formula",function(){

@@ -61,2 +119,32 @@ beforeEach(function(){

});
});
describe("When the module is executed with correct [String] first argument but of incorrect arithmetical formula and [Function] second argument",function(){
beforeEach(function(){
this.callback = jasmine.createSpy('callback');
this.incorrectList = incorrects;
this.stringMath = stringMath;
});
it('it should not throw an error',function(){
for(var incorrect of this.incorrectList){
expect(this.stringMath.bind(this,incorrect,function(){})).not.toThrowError();
}
});
it('it should call this function with error object as the first argument and result value equal to null as the second argument',function(){
for(var incorrect of this.incorrectList){
expect(this.stringMath.bind(this,incorrect,this.callback)).not.toThrowError();
expect(this.callback).toHaveBeenCalled();
expect(this.callback).toHaveBeenCalledWith(jasmine.any(Error), null);
}
});
it('it should return null',function(){
for(var incorrect of this.incorrectList){
expect(this.stringMath(incorrect,function(){})).toEqual(null);
}
});
});

@@ -22,3 +22,13 @@ module.exports = [

'3(/5)',
'3-(*6)'
'3-(*6)',
'e5',
'e+5',
'e-5',
'3e+',
'3e-',
'.4e+3.2',
'1.5e-1.25',
'2 e+3',
'2e +3',
'2e + 3'
];

@@ -60,2 +60,7 @@ module.exports = [

{expression:"-2*-2",result:4},
{expression:"5-1*-1",result:6},
{expression:"5+-1*-1",result:6},
{expression:"5 + -1 * -1",result:6},
{expression:"5--1*-1",result:4},
{expression:"5 - -1 * -1",result:4},
{expression:"(-2)*(-2)",result:4},

@@ -126,3 +131,24 @@ {expression:"-2*2",result:-4},

{expression:"3.5+5(-4-(3/(3+1)-12*3-.2*22)-16/4*12-5/(2)+3.5+2.5(1.5-2*7))-16",result:-225.5},
{expression:"12.436 - (2.15-1.6/.1) * (-8.33+(3 -1 *1.11)/ (3/(2.19+ .7*1)/1)+1)-11.5",result:-75.367805}
{expression:"12.436 - (2.15-1.6/.1) * (-8.33+(3 -1 *1.11)/ (3/(2.19+ .7*1)/1)+1)-11.5",result:-75.367805},
{expression:"1e-2",result:0.01},
{expression:".1e-2",result:0.001},
{expression:"1.234e+5",result:123400},
{expression:"1e-2+1e+2",result:100.01},
{expression:"1e-2 + 1e+2",result:100.01},
{expression:".2e-3 / 2e-5",result:10},
{expression:".1*1e+5*(.25e-5/.5)",result:0.05},
{expression:"1234567890000*1234567890000",result:1.524157875019052e+24},
{expression:"1/1000000",result:0.000001},
{expression:"1/10000000",result:1e-7},
{expression:"1/100000000",result:1e-8},
{expression:"1/1000000000",result:1e-9},
{expression:".25/123456789",result:2.0250000184275003e-9},
{expression:"123/-.25e-50",result:-4.92e+52},
{expression:"1.45*0e+10",result:0},
{expression:"0.055/(-5e-5)",result:-1100},
{expression:"5e+5*2e-3+5e+2/5e-4",result:1001000},
{expression:".5e+123 * .25e-123",result:0.125},
{expression:"(2e+2)",result:200},
{expression:"123/1000/2000/3000",result:2.05e-8},
{expression:"(2.5e-2*(.25e+2*(.05e+5*5e-2)))",result:156.25}
];
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc