Nutritious Pumpkin Meal

# npm

## exact-math

2.2.3 • Public • Published

# Description

The exact-math library is a set of methods for math calculations like: adding, subtracting, multiplying, dividing, rounding, flooring, ceiling and powering.
It also allows to use [String] math formulas, eg. 5.55*(7/.33)-2
It works with big numbers and small decimals and gives a precise result.
It allows to use [String|Number] values and it gives the [String|Number] result.

# Implementation

#### with NodeJS

npm install exact-math --save

#### Add exact-math.js library to the HTML file.

The library is located in ./dist/exact-math.js directory.
It is a webpack&babel bundled cross-browser library version.
The library is accessible as exactMath variable in the global (window) scope.

# Tests

> git clone https://github.com/devrafalko/exact-math.git
> cd exact-math
> npm install
> npm test


# Features

#### How it works:

• check out the calculation simulator that shows how the exact-math works compared with the JS regular arithmetic operations
• the program computes all possible combinations of calculations between minimal and maximal value entered
• put eg. min: 1 max: 5 step: 0.1 number: 2 select: multiplication

#### Floating point problem:

Code JavaScript result exact-math result
0.1 + 0.2 0.30000000000000004 0.3
0.4 * 0.2 0.08000000000000002 0.08
0.45 - 0.15 0.30000000000000004 0.3
.82 / 10 0.08199999999999999 0.082
1.4 - 0.6 - 0.4 - 0.4 -1.1102230246251565e-16 0

#### Big integers and small decimals

• If the value is not a safe integer (is bigger than 2⁵³-1 or lower than -2⁵³-1) [read more] the result of calculation is not precise
• the exact-math does the calculations on big integers and small decimals and gives a precise result

#### Arithmetic formulas

• in order to calculate the mathematical formulas, eg. 2*(5+.3)/13*(2.2*4), it must be the part of the code or the eval() method must be used
• the exact-math allows to calculate the [String] arithmetic formulas, using regular expressions to parse the given formula rather than eval() [see below]

#### Rounding integers and decimals

• the JavaScript Math.round method allows to round the value only to the nearest integers. In order to round the value to the chosen decimal place or to the tens, hundreds, thousands, etc., you need some workarounds
• the exact-math allows to round, floor and ceil the values both to the whole integers (ones, tens, hundreds, thousands, etc.) and decimals (tenths, hundredths, thousandths, ten-thousandths, etc.) [see below]

# Methods

### add, sub, mul, div

#### exactMath.add(x, y[, z[, ...]][, config][, callback])

add, sub, mul and div methods take the same arguments

#### x, y

Type: [Number|String]

• two or more [Number|String] numerical values must be passed as the arguments
• the third z argument and the next ones numerical values are optional
• the subtraction and division calculations are performed from left to right
• it accepts all legal [Number] values, eg: 1.5, 2e+3, -.4
• if the [String] argument is passed, it must be parse-able to the [Number] value, eg: '1.5', '2e+3', '-.4'
• it does not accept NaN, Infinity and -Infinity
• see the [samples]

### formula

#### exactMath.formula(formula[, config][, callback])

• the [String] formula is an arithmetical formula
• the exact-math uses regular expressions to parse [String] formula into the regular JavaScript formula
• mind that it does not use eval()
• see the [samples]
• The formula can contain:
• [0-9] digits
• 1.5, 0.5 or .5 decimal fractions
• -5, -.4, -5.55 negative values
• 2e-2, .25e+12, -3e-10 exponential notation values
• * multiplication sign (also x, × and ⋅ [see config.mulChar])
• / division sign (also : and ÷ [see config.divChar])
• + plus sign
• - subtraction sign
• ( and ) parentheses
• the arithmetic order of operations is respected:
• parentheses first
• then division and multiplication (from left to right)
• then addition and subtraction (from left to right)
• the multiplication sign can be omitted before parentheses; 4(2+1) is equal to 4*(2+1)
• the following signs combinations are allowed:
• 2 * -2 equals to 2 * (-2)
• 2 / -2 equals to 2 / (-2)
• +2 + 2 equals to 2 + 2
• 2 + +2 equals to 2 + 2
• -2 - -2 equals to -2 + 2
• -2 - +2 equals to -2 - 2
• -2 + -2 equals to -2 - 2
• the (multi)spaces between values, signs and parentheses are allowed:
• 2 + 2
• 2 + ( -2 - -2)
• 2 + (+2 + +4 / -1)
• -.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
• exponential notation formula: .2 e-5, 2e - 5, 3e +10

### round, ceil, floor

#### exactMath.round(value[, places][, config][, callback])

round, ceil and floor methods take the same arguments

#### value

Type: [Number|String]

• one [Number|String] numerical value must be passed as the argument
• it accepts all legal [Number] values, eg: 1.5, 2e+3, -.4
• if the [String] argument is passed, it must be parse-able to the [Number] value, eg: '1.5', '2e+3', '-.4'
• it does not accept NaN, Infinity and -Infinity

#### places

Type: [Number] (optional)
Default: 1

• the given value will be rounded (or rounded up when ceil or rounded down when floor) to the places digit
• the places must be a positive or negative [Number] integer
• the negative places value rounds the value to the decimals. The positive places value rounds the value to the integers.
• the 0 returns the given value without rounding it.
• when the places argument is omitted, the default 1 value is used
• study the table below and see the [samples]
places exactMath.round exactMath.floor exactMath.ceil
0 14993.00159 14993.00159 14993.00159
1 14993 14993 14994
2 14990 14990 15000
3 15000 14900 15000
4 15000 14000 15000
5 10000 10000 20000
6 0 0 100000
-1 14993 14993 14993.1
-2 14993 14993 14993.01
-3 14993.002 14993.001 14993.002
-4 14993.0016 14993.0015 14993.0016
-5 14993.00159 14993.00159 14993.00159

### pow

#### value

Type: [Number|String]

• one [Number|String] numerical value must be passed as the argument
• it accepts all legal [Number] values, eg: 1.5, 2e+3, -.4
• if the [String] argument is passed, it must be parse-able to the [Number] value, eg: '1.5', '2e+3', '-.4'
• it does not accept NaN, Infinity and -Infinity

#### power

Type: [Number] (optional)
Default: 2

• the given value will be raised to the power exponent
• the power must be a positive [Number] integer
• the value raised to the 0 power returns the 1 as a result, according to the approved mathematical convention
• when the power argument is omitted, the default 2 value is used
• see the [samples]

# config parameter

#### config

Type: [Object|Boolean] optional
Default: false

• each exact-math method may take the config argument. It allows to configure the additional settings.
• the config argument can be passed as [Object] object with config properties or as [Boolean] value
• if the config argument is passed as true, it is the shortcut of the config.returnString property set to true [samples]
• if the config argument is passed as false or if it is not defined (it is set to false by default then), it is the shortcut of the config.returnString property set to false [samples]
• if the config argument is passed as [Object] object, it may take the config properties [described below]
• if the config argument is not passed or if some [Object] config properties are not defined or defined with the incorrect type or value, the default values are used instead for these properties

### [Object] config properties:

#### returnString

Type: [Boolean]
Default: false

• by default, the [Number] value is returned as the result of the calculation
• if the result value is bigger (or lower) than a safe integer 2⁵³-1 or -2⁵³-1, the [Number] value may be inaccurate; Number('1111222233334444567') ==> 1111222233334444500
• if the returnString property is set to true, the accuare [String] value is returned; '1111222233334444567'.
• the [String] result can be used to the further exact-math calculations as it takes the [String] numerical value arguments [see above]
• see the [samples]

If you use [Number] unsafe values for the computation, the imprecise result is returned;
eg. exactMath.add(100000000000000000055,5.00000000000000022).
If you use [Number] safe values for the computation it may still return the imprecise unsafe result value;
eg. exactMath.mul(101101000110,10010110010001) => 1.0120321332222232e+24.
In order to avoid the imprecise results always use [String] numerical values for the calculations and set the config.returnString parameter to true.
The [String] numerical values passed as the arguments and the [String] result returned by the exact-math are always safe.

#### decimalChar

Type: [String|Array:string]
Default: ['.', ',']

• it applies only for [String] values
• in javaScript, the [Number] decimal fraction's notation requires the . period character, while out-of-coding notations sometimes also allows , comma character
• this setting lets to choose which characters are allowed for decimal fraction values (the characters other than . and , will be ignored). The default value will be used, if the illegal value has been passed
• the legal decimalChar settings samples: ',', '.', ['.'], [','], ['.', ','], etc.
• by default, the [String] value may contain the decimal fractions with both . and , character, eg: '4,5', '3.5 + 2,2', '0,55 / 6.22'.
• in order to allow only . character (and thereby forbid , character), set decimalChar property to [String] . or [Array] ['.']
• it may turn out handy especially for the end-users that will fill the inputs with some numbers or math formulas, that will be further passed through the exact-math module to calculate some result. The , usage would not throw an error then
• see the [samples]

#### divChar

Type: [String|Array:string]
Default: ['/', ':', '÷']

• it applies only for [String] formulas in the formula method
• in javaScript, the division operation requires the / character, while out-of-coding notations sometimes also allows : colon or ÷ division sign (unicode: '\u00F7') character
• this setting lets to choose which characters are allowed for formula division operations (the characters other than /, : and ÷ will be ignored). The default value will be used, if the illegal value has been passed
• the legal divChar settings samples: '/', ':', '÷' ['/', ':'], [':', '÷'], ['÷', ':', '/'], ['/'], etc.
• by default, the [String] formula may contain /, : and ÷ for division operations, eg: '22 / 4', 100:2, '4.5 * (5÷.1)/3'
• in order to allow only / character (and thereby forbid : and ÷ character), set divChar property to [String] / or [Array] ['/']
• it may turn out handy especially for the end-users that will fill the inputs with some division math formulas, that will be further passed through the exact-math.formula method to calculate some result. The : or ÷ usage would not throw an error then
• see the [samples]

#### mulChar

Type: [String|Array:string]
Default: ['*', 'x', '×', '⋅']

• it applies only for [String] formulas in the formula method
• in javaScript, the multiplication operation requires the * character, while out-of-coding notations sometimes also allows x letter, ⋅ dot operator (unicode: '\u22C5') or × multiplication sign (unicode: '\u00D7') characters
• this setting lets to choose which characters are allowed for formula multiplication operations (the characters other than *, x, × and ⋅ will be ignored). The default value will be used, if the illegal value has been passed
• the legal mulChar settings samples: '*', 'x', '×', '⋅', ['*', 'x', '×', '⋅'], ['*'], ['x'], ['*', '⋅'] etc.
• by default, the [String] formula may contain *, x, × and ⋅ for multiplication operations, eg: '5 * 4', 4x2, 3×6, '4.5 * (3x.2)*3', '3 ⋅ 3 \ 2'
• in order to allow only * character (and thereby forbid x, × and ⋅ character), set mulChar property to [String] * or [Array] ['*']
• it may turn out handy especially for the end-users that will fill the inputs with some multiplication math formulas, that will be further passed through the exact-math.formula method to calculate some result. The x, × or ⋅ usage would not throw an error then
• see the [samples]

#### eMinus

Type: [Number]
Default: 7

• it applies for the [String] results only (when the config.returnString property is set to true or when the callback is passed)
• by default, the [String] result for decimal values is parsed and written with exponential notation, if it has got 7 or more decimal places and it begins with zeros, eg. '0.01', '0.00001', but '0.1e-7' rather than '0.00000001'.
• set eMinus property to the other than default [Number] positive integer to decide when the decimal result should be written with exponential notation
• set Infinity if the decimal value should never be presented with exponential notation, regardless of how long the [String] decimal value is
• mind that eMinus does not round the value (like Number.prototype.toExponential) - it only shorten the long-zero values when possible, eg. the 0.123123123123123 will never be shorthened
• this setting may matter for example when the result value is directly printed for the user and you want to avoid displaying the exponential notation in the printed numbers
• it makes no difference for the exact-math, whether the [String] value with exponential notation, or without, is passed as the argument for the calculation: exactMath.add('0.00005','5e-5')
• see the [samples]

#### ePlus

Type: [Number]
Default: 21

• it applies for the [String] results only (when the config.returnString property is set to true or when the callback is passed)
• by default, the [String] result for integers is parsed and written with exponential notation if it has got 21 or more digits and it ends with zeros, eg. '10000', '10000000000', but '1e+21' rather than '1000000000000000000000' and 1000000000005e+8 rather than 100000000000500000000
• set ePlus property to the other than default [Number] positive integer to decide when the integer result should be written with exponential notation
• set Infinity if the integer value should never be presented with exponential notation, regardless of how long the [String] integer value is
• mind that ePlus does not round the value (like Number.prototype.toExponential) - it only shorten the long-zero values when possible, eg. the 123123123123 will never be shorthened
• this setting may matter for example when the result value is directly printed for the user and you want to avoid displaying the exponential notation in the printed numbers
• it makes no difference for the exact-math, whether the [String] value with exponential notation, or without, is passed as the argument for the calculation: exactMath.add('1e+21','1000000000000000000000')
• see the [samples]

#### maxDecimal

Type: [Number]
Default: 17

• it applies only to division calculations (also to division calculations in the formula method)
• if the result of division calculation is a decimal fraction with a huge or infinite number of decimal places, the maxDecimal property indicates the maximal number of decimal places of the [String] result value, to avoid stack overflow
• if the result value is a decimal fraction with the number of decimal places higher than the default 17, it is rounded to 17 decimal places
• in order to get more (or less) precise result, define maxDecimal property with a desirable integer value
• the maxDecimal [Number] value must be an integer, bigger or equal to 0 and cannot be an Infinity
• it does not round the results of addition, multiplication or subtraction calculations
• see the [samples]

#### divideByZeroError

Type: [Boolean|Error|Function]
Default: false

• by default false, when the value is divided by 0 or if the 0 is divided by 0 - the NaN is returned as the result
• set true in order to throw the default error; This error will be thrown only if the callback is not defined. Otherwise it is accessible via the error property in the callback function.
• set [Error] object and it will be thrown rather than the default error; This error will be thrown only if the callback is not defined. Otherwise it is accessible via the error property in the callback function.
• set [Function] and:
• This function is called rather than throwing error
• This function is called instead of callback function (if defined)
• If you return some value in this function, this value will be returned by the exact-math as the result of the calculation rather than the default NaN
• The function will be called with the one [Object] argument passed with the following properties:
• error: the default error
• index: the [Number] index of 0-value argument (for div method, otherwise it is undefined)
• list: the [Array] list of all passed values
• callback: the reference to the [Function] callback (if defined, otherwise it is undefined)
• see the [samples]

#### invalidError

Type: [Boolean|Error|Function]
Default: true

• by default true, if the argument of incorrect type has been passed, or if it hasn't been passed when required, or if any of the passed numerical value arguments is [String] incorrect value, is NaN, Infinity or -Infinity (that is forbidden) - the default error is thrown; This error will be thrown only if the callback is not defined. Otherwise it is accessible via the error property in the callback function.
• set false and the NaN will be returned as the result without throwing an error
• set [Error] object and it will be thrown rather than the default error; This error will be thrown only if the callback is not defined. Otherwise it is accessible via the error property in the callback function.
• set [Function] and:
• This function is called rather than throwing error
• This function is called instead of callback function (if defined)
• If you return some value in this function, this value will be returned by the exact-math as the result of the calculation rather than the default NaN
• The function will be called with the one [Object] argument passed with the following properties:
• error: the default error
• index: the [Number] index of the incorrect argument, (otherwise, if the error does not concern the argument, it is undefined)
• list: the [Array] list of all passed values
• callback: the reference to the [Function] callback (if defined, otherwise it is undefined)
• see the [samples]

#### trim

Type: [Boolean]
Default: true

• it applies to round, ceil and floor calculations
• by default true, when the value is rounded to the decimals, and there are some zero decimals at the end of the value (2.23000), they are trimmed (2.23)
• in order to keep the fixed number of decimal integers, set the trim config property to false
• have in mind to set the returnString config value to true, as the returned [Number] result value will have the last decimal zeros trimmed due to the default JavaScript behaviour
• see the [samples]
places value exactMath.round {trim: true} exactMath.round {trim: false}
-1 15.0006 15 15.0
-2 15.0006 15 15.00
-3 15.0006 15.001 15.001
-4 15.0006 15.0006 15.0006

# callback parameter

#### callback

Type: [Function] optional
Default: undefined

# Samples

### Install

npm i exact-math

### Repository

github.com/devrafalko/exact-math

3,821

2.2.3