el Guille, la Web del Visual Basic, C#, .NET y más...

Cálculos aritméticos en tu código con NCalc

 
Publicado el 24/Ago/2020
Actualizado el 24/Ago/2020
Autor: Guillermo 'guille' Som

El otro día me decidí a quitar la referencia al evaluador de expresiones de JScript de Microsoft (JScript.Eval.JScriptEvaluate) porque desde hace años está obsoleta (según la documentación de Microsoft, ya en Visual Studio 2005 lo estaba). Así que… buscando en la red de redes, me topé con NCalc que actualmente (a la hora de escribir esto el 24 de agosto de 2020) está disponible en GitHub. (publicado en mi blog)




 

Este contenido está obtenido de mi blog, la URL original es:
Cálculos aritméticos en tu código con NCalc

Pues eso… el otro día me decidí a quitar la referencia al evaluador de expresiones de JScript de Microsoft (JScript.Eval.JScriptEvaluate) porque desde hace años está obsoleta (según la documentación de Microsoft, ya en Visual Studio 2005 lo estaba).

Así que… buscando en la red de redes, me topé con NCalc que actualmente (a la hora de escribir esto el 24 de agosto de 2020) está disponible en GitHub.

Lo único que tienes que hacer es descargar el código, en el directorio Evaluant.Calculator hay un proyecto de C# que es el que debes usar en tu solución de Visual Studio y agregar una referencia, así, mediante el espacio de nombres NCalc podrás usar las clases (concretamente Expression) para hacer los cálculos aritméticos.

NOTA:
En mi sitio también tengo una DLL con código para evaluar expresiones (y funciones) que la hice con Visual Studio 2005 (en octubre de 2007) y que cuando fui a usarla en el proyecto que necesitaba el evaluador aritmético, me dio algún error (ya no recuerdo cuál) así que, decidí usar una que ya estuviese probada ampliamente y por eso me decidí por la de Microsoft JScript.
Y haciendo hoy alguna que otra prueba, me doy cuenta que falla en algo tan simple como 1*2*3+5, que en lugar de 11 me muestra 16, tal como sería si hubiese indicado 1*2*(3+5). Sin embargo esto si da el resultado correcto: 2*3+5 .En fin…
(¡Ya está solucionado, ese y otros fallillos que he ido encontrando! a ver si lo publico… )

Nota:
Aquí tienes el artículo sobre la nueva versión que he creado de EvaluarExpresiones.

NOTA:
El código de ejemplo que te muestro a continuación es solo para Visual Basic, ya que en la página de NCalc tienes abundantes ejemplos para C#.

¿Cómo evaluar expresiones aritméticas con NCalc?

La forma de usar NCalc es simple, primero creamos una instancia de la clase Expression pasándole como parámetro la expresión a evaluar (en el siguiente ejemplo, la variable texto, de tipo String, contiene la expresión a evaluar).

Dim exp As New NCalc.Expression(texto)

Para evaluar esa expresión indicada en el constructor llamamos al método Evaluate, el cual devuelve un valor de tipo Object con el resultado de dicha evaluación.

Dim res = exp.Evaluate()

Indicar variables en la expresión a evaluar

Si quieres evaluar una expresión que tenga argumentos (variables) puedes definir esas variables usando el método Parameters de la clase Expression.

En el siguiente ejemplo, están definidas las variables X y A y se usan en la expresión a evaluar.
En el primer caso, X se le asigna un valor fijo (10 en este caso) y a la variable A se le asigna el resultado de una expresión evaluada.

Dim exp As New NCalc.Expression("X + A")
exp.Parameters("X") = 10 ' "10*2"
exp.Parameters("A") = New NCalc.Expression("10 + 5").Evaluate
Dim res = exp.Evaluate()

Nota que si el valor que le asignas al parámetro está entre comillas dobles, se considera que es una cadena lo que estás asignado, no que evalúe el contenido de esa cadena.

Para probarlo, quita el comentario de la asignación del parámetro X para que sea: exp.Parameters(«X») = «10*2»
El resultado mostrado al evaluar X + A sería 10*215. Es decir, lo trataría como una cadena alfanumérica.

Usar variables de forma dinámica (o casi)

La clase Expression puede evaluar parámetros de forma dinámica, es decir, asignados externamente (o casi): Para ello en lugar de usar Parameters para definir esos valores se utiliza un delegado (o lo que se conoce como un método de evento) y en ese método se pueden indicar los valores que queramos… eso sí, esto no es realmente de forma dinámica, si no, que ya deben estar predefinidos… o casi…

En el siguiente ejemplo además de los valores de X y A está el valor de Pi, ese valor se obtiene desde el método de evento definido en el delegado del evento EvaluateParameter de la clase Expression.

Dim exp As New NCalc.Expression("X + A + Pi")
exp.Parameters("X") = 10
exp.Parameters("A") = New NCalc.Expression("10 + 5").Evaluate
AddHandler exp.EvaluateParameter, AddressOf evaluarParametro

Dim res = exp.Evaluate()

En ese método, tal como veremos en el siguiente código, se pueden definir otros valores que usemos en cualquiera de las expresiones evaluadas. Y si la variable contiene espacios o caracteres especiales, los podemos poner entre corchetes para que no den error.

Private Sub evaluarParametro(name As String, args As ParameterArgs)
    If name = "Pi" Then
        args.Result = 3.14
    ElseIf name = "Caña" Then
        args.Result = 17
    ElseIf name = "aleta" Then
        args.Result = 12
    ElseIf name = "gafas snorkel" Then
        args.Result = 8
    Else
        args.Result = 0
    End If
End Sub

La forma de usar los valores de Caña y gafas snorkel es de esta forma:

Dim exp As New NCalc.Expression("X + A + [Caña] + aleta * 2 + [gafas snorkel]")
exp.Parameters("X") = 10
exp.Parameters("A") = New NCalc.Expression("10 + 5").Evaluate
AddHandler exp.EvaluateParameter, AddressOf evaluarParametro

Dim res = exp.Evaluate()

Un par de consejos al usar NCalc

El primero y más importante es que los decimales hay que indicarlos siempre con puntos, independientemente de cómo lo tengas configurado en tu equipo.

El segundo es el uso de EvaluateOptions.IgnoreCase como segundo argumento en el constructor de la clase Expression, que supuestamente sirve para que al evaluar las expresiones (y los valores indicados en parámetros) no distinga entre mayúsculas y minúsculas. Pero como te digo, eso es lo que parece que dice la documentación, pero según he comprobado, solo funciona con las funciones internas no con los valores que tú hayas indicado en los parámetros o parámetros evaluados.

El tercero es que te leas la Wiki de NCalc, que aunque los ejemplos estén en C#, al menos puedas saber las diferentes funciones y operadores que se pueden usar.

Espero que te haya sido de utilidad, esa es siempre la idea.

Nos vemos.
Guillermo



 


La fecha/hora en el servidor es: 09/12/2024 22:09:09

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024