2

Brand New to NCalc.

I have a formula to be evaluated and Im getting some unexpected (to me) results.

The @T_No_Starters parameter used = 12.

If the formula is if (@T_No_Starters >= 8 ,'T','F') Result FALSE

If the formula is if (@T_No_Starters >= 8.0 ,'T','F') Result TRUE

If the formula is if (@T_No_Starters >= 10 ,'T','F') Result TRUE

Im not sure what is going on, why is 8 False yet 8.0 is True but 10 which is again a whole number is True? How can I ensure that the evaluation is always correct? Do I turn every number into decimal? Can I set something like a parameter type? WHen Im entering my parameters?

Below is the test code I use to arrive at the above.

Private Sub Button40_Click(sender As Object, e As EventArgs) Handles Button40.Click
        Dim FormulaLine As String = "if (@T_No_Starters >= 8 ,'T','F')"

        Dim Parms As New Dictionary(Of String, String)
        Parms.Add("T_No_Starters", 12)
        Dim OurAnswer = FormulaCalculator.MSGBOXEval(FormulaLine, Parms)
    End Sub

Function MSGBOXEval(Formula As String, Parms As Dictionary(Of String, String))

        Try
            Dim X As New Expression(Formula)
            For Each key As String In Parms.Keys
                X.Parameters.Add(key, Parms.Item(key))
            Next

            Dim result = X.Evaluate
            MessageBox.Show(result)
            Return result
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Return "Error " & ex.Message
        End Try

        Return 0
    End Function

I would best like to NOT change the values in the formula to decimal. Greater then or equal 8 starters not 8.0. It just doesen't look right. The Parameter dictionary is of string and string, I have to use it as some are strings. Is it as simple as making sure that the parameter is value when a value is required?

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
user1500403
  • 551
  • 8
  • 32

1 Answers1

2

It's a pretty late answer but I post it for future readers.

Your dictionary is made of strings:

Dim Parms As New Dictionary(Of String, String)

It doesn't matter original parameter type, VB will convert to string for you:

Parms.Add("T_No_Starters", 12)

It's equivalent to:

Parms.Add("T_No_Starters", "12")

Now it's obvious that you're adding parameters as strings:

Dim X As New Expression(Formula)
For Each key As String In Parms.Keys
    X.Parameters.Add(key, Parms.Item(key))
Next

NCalc will try to convert types and evaluate expression without errors:

if (@T_No_Starters >= 8 ,'T','F')

It's equivalent to:

if (@T_No_Starters >= '8' ,'T','F')

Because it's a string comparison (without natural ordering) then '12' >= '8' is correctly FALSE (and other examples become reasonable too).

What you should do? Just change type of your dictionary to avoid any implicit conversion, let NCalc do this for you:

Dim Parms As New Dictionary(Of String, Object)

And:

Function MSGBOXEval(Formula As String, Parms As Dictionary(Of String, Object))

Note that using Object you are still able to add any type to your dictionary:

Params.Add("T_Text", "some text") 
Params.Add("T_Beginning", DateTime.Now)
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • thanks for answering the question, I have gone another way around it but your solution does look far more elegant then the hack I did :) – user1500403 Sep 09 '15 at 05:37
  • Yes, I supposed you already solved your issue (answer is little bit old) but I posted answer in case someone else has same problem (not do many ncalc questions around here) – Adriano Repetti Sep 09 '15 at 05:51