Diferencias con el ex4j original » Histórico » Revisión 3
Revisión 2 (Federico Vera, 2018-07-12 22:30) → Revisión 3/4 (Federico Vera, 2018-07-13 07:54)
# Diferencias con el ex4j original {{>toc}} # Nota Existen muchas diferencias con `exp4j` original, algunas de las cuales pueden causar problemas de compatibilidad para usuarios avanzados de `exp4j`. # Diferencias Generales Entre los cambios mas significativos de esta versión de `exp4j` se encuentran: un simplificador (preevaluador), manejo de variables, funciones adicionales, enums, [[Diferencias_con_el_ex4j_original#Constantes-como-funciones|*constantes como funciones*]] e impresión de tokens. ## Simplificador (preevaluador) El simplificador es una funcionalidad intereante ([discusión original](https://github.com/fasseg/exp4j/issues/26)) cuando las expresiones tienen operaciones conocidas en tiempo de creación, por ejemplo, consideremos la expresión `2^x + 4 / 2` que puede convertirse en `2^x + 2`. No parece demasiado.... o si? la realidad es que al utilizar múltiples evaluaciones, muchas constantes varios valores de `x` (por ejemplo al graficar) esta diferencia es muy notoria ([primera prueba de performance](https://github.com/fasseg/exp4j/issues/26#issuecomment-70547026)). Otra simplificación interesante es al utilizar expresiones del tipo `if(exp, v_true, v_false)`, el simplificador puede quitar (en algunos casos) el bloque `if` completo, por ejemplo `if(1 > 0 & 3 < 4, a * pi(), e())` se convierte en `a * pi()` (de hecho en `if(1, a * pi(), e())`... _Todavía estoy trabajando en esto..._ ### Usando el simplificador Por defecto se encuentra desactivado, dado que no es realmente necesarios cuando se ejecuta una operación una sola vez (el simplificador hace toda una evaluación para funcionar). Para activar el simplificador simplemente es necesario pasar `true` al builder: ~~~java // por defecto ExpressionBuilder#build() es #build(false) Expression ex = new ExpressionBuilder("2^3 + 4 / 2").build(true); double result = ex.evaluate(); ~~~ ### Una pequeña nota Un simplificador _**debería**_ simplificar solamente funciones determinísticas, por lo tanto ahora disponemos de una bandera `deterministic` en el constructor de las funciones (valor por defecto `true`). Por lo tanto si utiliza funciones [no deterministas](https://es.wikipedia.org/wiki/Algoritmo_no_determinista) deberá cambiar la declaración de la función a: ~~~java Function rand_deterministica = new Function("randd", 0) { @Override public double apply(double... args) { // Falla épica de simplificación return Math.random(); } }; ~~~ A esto: ~~~java Function rand_NO_deterministica = new Function("randnd", 0, false) { // Esta bandera ^^^^^ @Override public double apply(double... args) { return Math.random(); } }; ~~~ Este cambio puede resultar molesto para aquellos que utlicen muchas funciones no deterministas... aunque dado que el simplificador está desactivado por defecto, la mayoría de la gente no debería tener problemas. ## Manejo interno de variables Internal variable handling Esto no es un cambio muy importante, la idea es mejorar un poco el rendimiento, evitar errores y generar un código mas legible. Pero no honra la filosofía de _inmutabilidad_ de las calculadoras basadas en stacks, así que si desea comenzar a hackear This isn't really an issue in itself, it makes `exp4j` va a tener que tomar esto en cuenta. 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. ### Entonces... ¿cuál es el cambio? So... what's the change? El cambio The real es changes is commit:d2d96fce y en and in commit:7f280988 puede verse una de las situaciones que se generan. 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. Esta versión de This version of `exp4j` usa el mismo uses the same token para todas las instancias de una for each and every time a variable en una expresión (en versiones anteriores existían situaciones en las que podía tenerse varios valores diferentes para una sola variable. is present in an expression, which means that the moment you set a variable it was changed in every occurrence. ## Impresión de tokens Enums instead of final int variables A partir de esta versión es posible imprimir la representación interna de una expresión. 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. ### ¿Cómo? 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!_). Las dos formas básicas son: ### 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[+] ~~~ ## Constantes como funciones Finalmente nos encontramos con el cambio que va a resultar mas molesto por algunos usuarios, y el que tiene mas probabilidades de _romper cosas_. En la verisión 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 de `exp4j` las constantes eran declaradas como variables inmutables, pero en esta versión de `exp4j` son declaradas como funciones, por lo tanto una expresión como the constants where declared as simply constants, in this version constants are declared as functions so for instance `d * pi` pasa a ser is now `d * pi()`. 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. ## Traducciones Todos los mensajes y advertencias pueden ser traducidos, y ya se tiene la primera traducción al Español ## Serialización Todas las expresiones son `Serializable`s! ## Funciones adicionales * [[Funciones Incluidas]] * [[Operadores Incluidos]] * [[Funciones y Operadores adicionales]]Volver al inicio