C++ Math Evaluator

Siguiendo con mis experimentos en teoría de lenguajes, hice una librería en C++ que permite evaluar y reconocer una expresión matemática entre otras cosas.

Estas son las características:

Operadores

&& ||
== != < > <= >=

  • + –
  • * / %
  • ^
  • !
  • Scientific notation

Funciones

  • factorial
  • log
  • acot
  • acosh
  • sign
  • acos
  • asech
  • atan
  • asinh
  • atanh
  • acoth
  • asin
  • acsc
  • acsch
  • asec
  • cot
  • coth
  • csc
  • csch
  • log10
  • log2
  • sec
  • sech
  • sqrt
  • tan
  • rand_0_to_1
  • sin
  • cos

Constantes numéricas:

pi
e
g (gravity)
random (random number)

User defined variables:

char expression[] = "sin(pi + x)";        
p.get_vars().add("x", 1.0);
p.parse(expression);
double result = p.get_numeric_answer();

Reconocimiento (saber si la expresión está bien escrita):

try {
    char expression[] = "pi^2.0 - sin(cos(tan(3.2e0)";
    p.evaluate_expression_with_exception(expression);
    cout << "Ok ... " << endl;
} catch(ParsingException ex) {
    cout << "Error: " << ex.get_msg() << endl;
}

Evaluation:

try {
    char expression[] = "pi^2.0 - sin(cos(tan(3.2e0)))";
    p.evaluate_expression_with_exception(expression);
    p.parse(expression);
    double r = p.get_numeric_answer();
    cout << "Ok ... " << r << endl;
} catch(ParsingException ex) {
    cout << "Error: " << ex.get_msg() << endl;
}

Arrays:

Parser p;
p.get_arrays().create_array("a");

for(int i = 1; i <= 10; i++) {
    p.get_arrays().add_element_to_array("a", (double)i);
}

try {
    char expression[] = "a[sin(pi) + 2]^3";
    p.parse(expression);
    double r = p.get_numeric_answer();
    cout << "Ok ... " << r << endl;
} catch(ParsingException ex) {
    cout << "Error: " << ex.get_msg() << endl;
}

Tokenization:

try {
    char expression[] = "a[sin(pi) + 2]^3";
    Parser p;
    p.extract_tokens(expression);

    vector<Lexema> tokens = p.get_lexemas_positions();

    for(size_t i = 0; i < tokens.size(); i++) {
        cout << tokens[i] << endl;
    }

} catch(ParsingException ex) {
    cout << "Error: " << ex.get_msg() << endl;
}

Salida:

{a, init(0), tipo(OPERADOR)}
{[, init(1), tipo(DELIMITADOR)}
{sin, init(2), tipo(FUNCION)}
{(, init(5), tipo(DELIMITADOR)}
{pi, init(6), tipo(VARIABLE)}
{), init(8), tipo(DELIMITADOR)}
{+, init(10), tipo(DELIMITADOR)}
{2, init(12), tipo(NUMERO)}
{], init(13), tipo(DELIMITADOR)}
{^, init(14), tipo(DELIMITADOR)}
{3, init(15), tipo(NUMERO)}

Function domain checking (trigonometric functions):

try {
    Parser p;
    char expression[] = "1 + asin(1.2)";
    p.evaluate_expression_with_exception(expression);
    p.parse(expression);
} catch(ParsingException ex) {
    cout << "Error: " << ex.get_msg() << endl;
}

Output:

Error: out of domain for function '1.200000'

La librería la pueden descargar de github:

https://github.com/leogtzr/math_evaluator_cpp

 

Saludos.

 

Publicado en Uncategorized | Etiquetado , , , | 1 Comentario

Yarelang, mi lenguaje de programación

Hace un tiempo he estado desarrollando (en mis ratos libres) un lenguaje de programación, he hecho otro avance, he agregado soporte para todas las funciones trigonométricas:

  • abs
  • acos
  • acosh
  • acot
  • acoth
  • acsc
  • acsch
  • asec
  • asech
  • asin
  • asinh
  • atan
  • atan2
  • atanh
  • cos
  • cosh
  • cot
  • coth
  • csc
  • csch
  • exp
  • log
  • log10
  • log2
  • max
  • min
  • mod
  • real
  • sec
  • sech
  • sign
  • sin
  • sinh
  • sqrt
  • tan
  • tanh

Además le he dado una arreglada al código, he quitado cosas innecesarias.

Les dejo la referencia del lenguaje y algunos ejemplos de uso por si alguien gusta probarlo.

Cualquier sugerencia es bien recibida.

https://leonardogtzr.wordpress.com/2013/03/09/yare-un-lenguaje-de-programacin-propio/

El código fuente lo pueden consultar en mi cuenta de github:

https://github.com/leogtzr/yarelang-c–Imagen

Publicado en Programación | Etiquetado , , , , , | Deja un comentario

MathExpressions v1.11 librería matemática

He añadido algunas mejoras a la librería y corregido algunos bugs.

Imagen de uso:

1

Pueden descargarla y ver el código fuente desde el repositorio en GitHub.

Ver código fuente: https://github.com/leogtzr/java-mathexpressions

https://github.com/leogtzr/java-mathexpressions/archive/master.zip

Publicado en Programación | Deja un comentario

MathExpressions v1.1 librería matemática

He realizado una mejora a la librería de expresiones matemáticas: MathExpressions v1.0 librería matemática)

En esta nueva versión puedes saber si una expresión está bien escrita o mal escrita, es decir, en esta versión se hace una separación de el reconocimiento (saber si está bien o mal la expresión) con la evaluación (obtener el valor numérico que representa la expresión).

Lo siguiente es una prueba de uso:

Imagen

Y este es el resultado:

Imagen

Este es el enlace a la librería:

https://dl.dropboxusercontent.com/u/58795303/mathexpressionsv1.1.jar

Y de aquí pueden descargar la documentación:

https://dl.dropboxusercontent.com/u/58795303/javadocv1.1.rar

Cualquier comentario o sugerencia es bien recibida.

Saludos.

Publicado en Programación | Etiquetado , , | Deja un comentario

MathExpressions v1.0 librería matemática

He escrito una librería en Java para evaluar expresiones matemáticas de cualquier índole, por ejemplo:

1+2*sin(pi) – 4 * cos(pi) – g^2

Esta librería incluye las siguientes funciones trigonométricas y no trigonométricas:

Seno, factorial, logaritmo natural, cotangente inverso, coseno hiperbólico inverso, coseno inverso, secante hiperbólico inverso, tangente inverso, seno hiperbólico inverso, tangente hiperbólico inverso, cotangente hiperbólico inverso, seno inverso, cosecante inverso, cosecante hiperbólico inverso, secante inverso, cotangente, cotangente hiperbólico, cosecante, cosecante hiperbólico, logaritmo 10, logaritmo 2, secante, secante hiperbólico, sqrt, tangente, aleatorios entre 0 y 1 y aleatorios con rango.

Pueden ver el API y darse una idea de lo que trae la librería.

La librería hace comprobaciones de dominio para las funciones antes citadas (solo para las que aplique un dominio).

Ejemplo sencillo de uso:

1

Su uso es muy sencillo, hay que crear una instancia de Parser, luego invocamos al método parse(String) pasándole un String y este se encarga de evaluarla dejando el resultado listo para ser consultado con el método getRespuestaNumerica().

2

La librería tiene licencia GPL v3.

Instalación.

Uso en NetBeans

Crear un proyecto Java, dar clic derecho en el proyecto, elegir Propiedades (al final de todas las opciones), elegir Libraries y dar clic en el botón “Add JAR/Folder”:

4

Buscar o explorar el archivo MathExpressions.jar y dar en Abrir, eso es todo.

Uso fuera de NetBeans

3

Si prefieren no usar el .jar y usar los archivos .java igual está bien, solo hay que descomprimir el archivo .jar, son 3 clases las que contiene esta librería.

El JavaDoc para la librería lo pueden descargar de aquí:
https://dl.dropboxusercontent.com/u/58795303/MathExpressions%20Javadoc.rar

La librería la descargan de aquí:
https://dl.dropboxusercontent.com/u/58795303/mathexpressions.jar

Si encuentrar errores o si tienen alguna sugerencia, todo es bienvenido.

La librería es facilmente implementable en C#, quizás la haga en un rato más.

PD: He convertido la librería a C#, aquí está:

https://dl.dropboxusercontent.com/u/58795303/MathExpressionsCSharp.rar

¡Saludos!

Publicado en Programación | Etiquetado , , , , , , , , , , | 8 comentarios

Java – Enumeraciones avanzadas

Como en otros lenguajes de programación, una enum o un tipo enum en Java es una variable que puede tener un conjunto de constantes predefinidas.

¿Y para qué me sirve eso?

Pongamos el siguiente ejemplo,  nosotros necesitamos representar el valor de los días de la semana, podríamos lograrlo utilizando constantes y variables int de la siguiente manera:

Imagen

¿Hasta aquí todo bien, pero qué pasaría si alguien hiciera esto?

Imagen

¿Cuál debe ser el valor de sumar DOMINGO + SABADO?

Simplemente no tiene lógica ni significado, nosotros necesitamos de una variable que almacene un solo valor y ¡SOLO ESE VALOR!

Para eso nos viene perfecta una enumeración, esta es la sintaxis en Java:

Imagen

enum + Identificador + CONSTANTES

Y la asignación la podemos hacer así:

Imagen

Y solamente así, debido a  que los constructores en los enums son privados, por lo tanto es un error de compilación usar new para intentar hacer una instancia de una enum primitiva.

Los enums pueden tener métodos

Las enums pueden tener métodos, no solo nos sirven para representar un tipo o un número ordinal, podemos tener algo así:

Imagen

Y podemos invocar ese método así:

Imagen

Ó así:

Imagen

Los enums pueden tener constructores y variables de instancia, ejemplo:

Imagen

Cuando haces:

Imagen

Internamente el enum asocia esa constante a su constructor:

Imagen

Es decir, pasa ese 1 que está en la constante dentro del enum a su constructor.

Podemos pasar lo que necesitemos, un ejemplo (sin utilidad) es el siguiente:

Imagen

En este ejemplo hemos utilizado ya una referencia y no una variable primitiva.

Comportamiento específico para cada constante

En ocasiones podemos necesitar que cuando se invoque a una constante se invoque a un método específico para esa constante, es por esto que las enumeraciones brindan la posibilidad de incluír métodos abstractos para que dentro de cada constante tengas que sobreescribir ese método y dar un comportamiento específico, veamos un ejemplo:

Imagen

Como se puede observar hemos declarado un método abstracto llamado getRGB que regresa un array de ints, al hacer esto estamos obligados a dar una implementación en el bloque de cada constante.

Podemos utilizarlo así:

Imagen

A continuación alguna de las reglas que tienen las enumeraciones:

  • No se pueden hacer operaciones aritméticas entre enumeraciones, a menor que sea entre los métodos internos de la enumeración, ejemplo:Imagen
  • Todas las enumeraciones extienden de la clase Enum, pueden consultar el API para ver otros métodos interesantes aparte del ordinal().
  • Dentro de cada bloque de las constantes podemos tener n cantidad de métodos, pero solo los que estén sobrescribiendo los métodos abstractos tendrán visibilidad fuera de la enumeración.
  • Las enumeración son otro tipo de variable que puede utilizarse en un switch.
  • Las enumeraciones al igual que las clases pueden estar en archivos separados y aplican las mismas reglas de modificadores de acceso que para las clases.
  • Los constructores de una enumeración siempre son privados, SIEMPRE, es un error intentar hacer esto:
  • Imagen
  • Las enumeraciones ya implementan el método toString().
  • Las enumeraciones pueden tener variables de instancia tal como las clases.
  • Pueden utilizar el método values() para obtener las constantes de la enumeración.

Eso es todo, espero les sea de utilidad, cualquier comentario es bien recibido.

¡Saludos!

Publicado en Programación | Etiquetado , , , , , , | 2 comentarios

Java – Método toString()

Hay ocasiones en las que creamos una instancia y nos interesa conocer el estado de este objeto, con estado me refiero a cómo está conformado el objeto o cuáles son los valores de sus propiedades (variables de instancia). Por ejemplo, suponiendo que tuviéramos una clase así:

Imagen

Y suponiendo que quisiéramos imprimir el objeto de la siguiente manera:

Imagen

Esto nos devolvería:

Imagen

Lo cual no representa en absoluto el “estado” del objeto, es decir su contenido. Lo que nosotros buscamos es obtener una representación textual de nuestro objeto, y para eso debemos de sobreescribir en nuestra clase el método toString() el cuál es heredado desde la clase Object.

Podríamos hacer algo así:

Imagen

Con lo cual obtenemos algo así:

Imagen

Cabe destacar que por defecto el método System.out.println() invoca al método toString() de nuestro objeto, pero podríamos usar el método toString() de manera explícita de la siguiente manera:

Imagen

Al igual que los demás métodos de nuestra clase el método toString() debe ser mantenido, por ejemplo, si una nueva variable de instancia es añadida a la clase esta debe ser tratada por el método toString().

Conclusión, sobreescribir el método toString() es una buena práctica y sobre todo tiene buenos beneficios a la hora de depurar.

¡Saludos!

Publicado en Programación | Etiquetado , , , | Deja un comentario