BigDecimal Mode

With Jep 3 and later, it is possible to evaluate expressions using decimal arithmetic. This allows calculations to be performed with specified accuracy or even unlimited accuracy. If you are running into precision problems or already know that you will require the highest possible precision in your calculations, we recommend using this operation mode.

Rather than using the double type to represent numbers, BigDecimal is used. The BigDecimal class is part of the Java API and is contained in the java.math package. For more information on this class, please read the BigDecimal documentation.

The difference in the accuracy is best shown through an example. When performing multiplication of two numbers of the double type,

    10*0.09 evaluates as 0.8999999999999999.

But when performing the same calculation using decimal arithmetic with the BigDecimal type,

   10*0.09 evaluates as 0.9.

Note, care is needed when using BigDecimals as

   10.0*0.09 evaluates as 0.90.

a subtly different BigDecimal value.

top

How to use BigDecimal mode

Using Jep in BigDecimal mode is simple. Simply create a new Jep instance using the BigDecComponents with:

import com.singularsys.jep.bigDecimals.BigDecComponents;

...

jep = new Jep(new BigDecComponents());

This initializes Jep with a special the BigDecNumberFactory, BigDecOperatorTable and BigDecFunctionTable. By default, the math context is set to unlimited precision. But you can also initialize the components with a different math context. For example, to use 32-bit precision numbers simply use

jep = new Jep(new BigDecComponents(MathContext.DECIMAL32));

For more information about MathContext refer to the Oracle MathContext JavaDoc.

The package can also be setup to use fixed-point arithmetic, for two-decimal places use:

jep = new Jep(new BigDecComponents(2));
top

Supported Operators and Functions

Guaranteeing precision unfortunately comes at the cost of more complex algorithms for basic operators and functions. For this reason, some functions and operators available for double arithmetic are not available in the BigDecimal mode.

The supported operators and functions are below. These are all available by default with the BigDecComponents.

+, -, *, /, ^ (power), % (modulus)

>, <, >=, <=, == (equals)

!= (not-equals)

&& (and), || (or), ! (not)

Functions Description Class
round(val),
round(val,dp)
Round numbers. Two argument version round to a specific number of decimal places. BigDecRound
rint(val)
rint(val,dp)
Round numbers, with the round half even rounding mode. BigDecRound
ceil(val)
floor(val)
Floor and ceiling functions. BigDecRound
roundSF(val,sf) Round numbers to a specified number of significant figures. BigDecRoundSigFig
abs(val) Absolute value function. BigDecAbs
signum(val) Sign of the argument either -1, 0 or 1. BigDecSignum
if(cond, true_val, false_val) If function. If
min(val1,val2,...)
max(val1,val2,...)
Min and Max functions. BigDecTieBreakComparative,
MinMax
sum(val1,val2,...) Sub of the arguments. BigDecSum
vsum([val1,val2]) Sub of the arguments, expanding any arguments. BigDecVSum
avg(val1,val2,...) Average Average

Just like with Jep in standard mode, you can add your own custom functions.

top

BigDecimal and Vectors

Since Jep 4.1 the package supports operations on vectors of big decimals numbers. The operators +, -, * (multiplication by a scalar), / (division by a scalar), == (equals) != (not-equals), work with vectors of big decimals, and the functions vsum (sum the elements of a vector), sum (sum the vector), avg (mean of the elements of a vector), min (minimum element of a vector), max (maximum element of a vector), count (number of the elements in a vector).

Node n = jep.parse("u=[1,2,3]");
var res = jep.evaluate(n);
n = jep.parse("v=[4,5,6]");
res = jep.evaluate(n);
n = jep.parse("u+v");
res = jep.evaluate(n);  // [5,7,9]
n = jep.parse("u.v");
res = jep.evaluate(n);  // 32
n = jep.parse("u * v[2]");
res = jep.evaluate(n);  // [5,10,15]

BigDecimal and Strings

By default BigDecimal and Strings cannot be used together but as of release 3.4 this can now be turned on. The following code switches on this facility and adds the standard string functions.

// Create the BigDecComponents
BigDecComponents compSet = new BigDecComponents(MathContext.DECIMAL64,true);
// Create a jep instance
jep = new Jep(compSet);
// Add the standard set of string functions
jep.setComponent(new StringFunctionSet());

The above code will allow strings to be concatenated using '+' and compared using '==', '!=', '<', '<=', '>=', '>'. The StringFunctionSet allows the left, right, lower, upper, substring, len, mid, trim.