Differences with the original exp4j » Histórico » Revisión 3
Revisión 2 (Federico Vera, 2018-07-08 05:50) → Revisión 3/6 (Federico Vera, 2018-07-12 06:00)
{{>toc}}
# Differences with the original exp4j
# Note
There are some key differences with original `exp4j`, some of which will cause compatibility issues for advanced `exp4j` users (API differences radicate in some corner cases).
# Core differences
This version of `exp4j` has several internal changes, which include but are not limited to: a naive simplifier, variable handling, extra functions, enums in code, constants as functions and token printing.
## Naive Simplifier
The simplifier is a nice feature ([Original discussion](https://github.com/fasseg/exp4j/issues/26)) when you have operations that can be resolved the use of variables, for instance consider the expression `2^x + 4 / 2` could be turned into `2^x + 2`. Doesn't seem like much... does it? but when you use multiple formulas, lots of constants, multiple `x` values (i.e. plotting) this little difference comes in handy ([First performance test](https://github.com/fasseg/exp4j/issues/26#issuecomment-70547026)).
The other nice trick is when using expressions like `if(exp, v_true, v_false)`, the simplifier could remove the entire `if` block, for instance `if(1 > 0 & 3 < 4, a * pi(), e())` will be converted to `a * pi()` (actually to `if(1, a * pi(), e())`... _I'm still working on it..._
### Using the Simplifier
The simplifier is disabled by default, since it's really not needed when evaluating an expression only once (the simplifier needs to do one whole evaluation in order to work).
To activate it simply pass `true` to the builder:
~~~java
// by default ExpressionBuilder#build() is #build(false)
Expression ex = new ExpressionBuilder("2^3 + 4 / 2").build(true);
double result = ex.evaluate();
~~~
### A little note
A simplifier _**should**_ only simplify deterministic functions, so there's now a `deterministic` flag in each function creation (`true` by default). So if you have [non-deterministic](https://en.wikipedia.org/wiki/Nondeterministic_algorithm) functions in your code, you'll need to change your function declaration from this:
~~~java
Function rand_deterministic = new Function("randd", 0) {
@Override
public double apply(double... args) {
// This will be an epic simplification fail
return Math.random();
}
};
~~~
To this:
~~~java
Function rand_NOT_deterministic = new Function("randnd", 0, false) {
// This flag ^^^^^
@Override
public double apply(double... args) {
return Math.random();
}
};
~~~
This will be the most annoying thing for users with lot's of custom non-deterministic functions... although most users should not notice it (simplifier is disabled by default)
## Internal variable handling
This isn't really an issue in itself, it makes `exp4j` gain some performance, avoid possible errors, and improve code readability. But doesn't honor the _inmutable token_ filosophy of both `exp4j` and stack based calculators, so if you want to start hacking in this fork you should take this into account.
### So... what's the change?
The real changes is commit:d2d96fce and in commit:7f280988 you can see an example of one the pitfalls.
The original `exp4j` uses one token per variable, that's to say one token each time a variable is present in an expression which creates every time a variable is set, a state where the same variable has a different values in an expression. That's really a no go for me.
This version of `exp4j` uses the same token for each and every time a variable is present in an expression, which means that the moment you set a variable it was changed in every occurrence.
## Enums instead of final int variables
This should not be a problem for anybody, but it's necessary to address the change `->` commit:39dff556.
## Token printing
Some might call this a debugging tool, others the reason of a 50% increase in the final jar size, I simply call it token printing... it allowed me create a view of the internal expression.
### Why should you care?
Well the thing is, you probably won't, but there are some cases when using this sort of tools for research you need a way to audit the internals of the expression, not to try and guarantee result reproducibility, but to build extra trust in the expression that's being evaluated (_also... it's an awesome debbuging tool!_).
### How to print the tokens?
The two basic ways are:
~~~java
Expression exp = new ExpressionBuilder("2x + 1").variable("x").build();
String out1 = exp.toString();
// out1 -> 2.0 x * 1.0 +
String out2 = exp.toTokenString();
// out2 -> NUMBER[2.0] VARIABLE[x] OPERATOR[*] NUMBER[1.0] OPERATOR[+]
~~~
## Constants as functions
We finally got to the change that will annoy most users and it's the change that will most probably _break_ things. In the original `exp4j` the constants where declared as simply constants, in this version constants are declared as functions so for instance `d * pi` is now `d * pi()`, this isn't an extreme change, but the reasoning is: some times your variables can have the name of constants... since users are not expected to know each and every constant implemented in `exp4j` this can cause trouble.
## Extra functions
Checkout the wiki pages for:
* [[Built in Functions]]
* [[Built in Operators]]
* [[Extra Functions and Operators]]
Volver al inicio