Local Variables

 

See Also: ucDefineVariable

 

uCalc lets you define variables that are local to an expression.  The definition is done within the expression itself.  If a variable with the same name was already defined, the local variable will not interfere with the previously defined variable of the same name.  A local variable can hold a separate value from the previously defined variable.  An expression can have any number of local variables, separated by commas.

 

 

Example 1: Multiple local variables in an expression

 

This example uses two local variables: x, and y.  After the expression is finished, x reverts to being undefined, and y still has its original value of 123, which it had before the expression was evaluated.

 

Visual Basic

ucDefineVariable "y = 123"

 

Print ucEvalStr("Local(x, y, (uc_For(x, 1, 5, 1, SetVar(y, y+x^2)); y))") ' Returns 55

Print ucEvalStr("x") ' Returns an error: Undefined identifier

Print ucEvalStr("y") ' Returns 123

 

 

Example 2:  Local variable, and ByHandle argument (Summation)

 

This example defines a summation routine named Sum().  The actual callback function is named Sum_(), and requires 5 arguments, where the last one is a variable passed ByHandle.  A syntax construct named Sum() is defined so that the last two arguments are optional.  The last argument is made local.  If omitted it defaults to a variable named x.  By making it local you don't have to worry about defining a variable ahead of time for use with Sum().  Plus it will not interfere with another variable of the same name, whether it is outside the expression, or Sum is nested several times within the same expression.  Expressions such as the following can be entered:

 

Sum(x^2, 1, 10)               ' returns 385

Sum(n+5, 1, 25, 1, n)         ' returns 450

Sum(Sum(x^2, 1, 10)*10, 1, 5) ' returns 19250

 

Visual Basic

' The following 3 lines can be placed in Form_Load()

ucDefineFunction "Native: Sum_(ByExpr Expr, Start, Finish, Step, ByHandle Var)", AddressOf ucSum

ucDefineSyntax "Sum({Expr}, {Start}, {Finish} [, {Step=1} [, {Var=x}]])" _

             + "::= Local({Var}, Sum_({Expr}, {Start}, {Finish}, {Step}, {Var}))"

 

' The following callback routine goes in a separate module, such as DemoVB.Bas

Sub ucSum(ByVal Expr As Long)

   Dim Expression As Long, VarHandle As Long

   Dim Start As Long, Finish As Long, sStep As Long

   Dim x As Double, Total As Double

 

   Expression = ucArgHandle(Expr, 1)

   Start = ucArg(Expr, 2)

   Finish = ucArg(Expr, 3)

   sStep = ucArg(Expr, 4)

   VarHandle = ucArgHandle(Expr, 5)

 

   For x = Start To Finish Step sStep

      ucSetVariableValue VarHandle, x

      Total = Total + ucEvaluate(Expression)

   Next

 

   ucReturn Expr, Total

End Sub

 

This same example is also found in the source code for the demo program for C#, C++ Builder, PB, VB (classic), VB.NET, and VC++.

 

 

Example 3:  Local variable, and ByHandle argument (Equation Solver)

 

The concept in this example is very similar to that of the previous example.  This routine is a simple equation solver based on an adaptation of the bisection method algorithm.  This code is just enough to get you started.  You will want to add to it for a more robust solver.  Here are examples of equations it can solve:

 

Solve(x^2 + 1 = 26)           ' returns  5

Solve(x^2 + 1 = 26, -1000, 0) ' returns -5

 

Visual Basic

' The following lines can be placed in Form_Load()

ucDefineFunction "Native: Solve_(ByExpr Expr, a, b, ByHandle Var)", AddressOf ucSolve

ucDefineSyntax "Solve({Expr} [, {a=-100000000} [, {b=100000000} [, {Var=x}]]]) " _

             + "::= Local({Var}, Solve_({Expr}, {a}, {b}, {Var}))"

ucDefineSyntax "Solve({Left} = {Right} [, {etc}]) ::= Solve({Left}-({Right}) {etc: , {etc}})"

 

' The following callback routine goes in a separate module, such as DemoVB.Bas

Sub ucSolve(ByVal Expr As Long)

   Dim Expression As Long, Variable As Long, Iterations As Long

   Dim a As Double, b As Double, fa As Double, fb As Double

   Dim Value As Double, tmp As Double

 

   Expression = ucArgHandle(Expr, 1)

   a = ucArg(Expr, 2)

   b = ucArg(Expr, 3)

   Variable = ucArgHandle(Expr, 4)

 

   ucSetVariableValue Variable, a: fa = ucEvaluate(Expression)

   ucSetVariableValue Variable, b: fb = ucEvaluate(Expression)

  

   If fb < fa Then tmp = a: a = b: b = tmp   'swap a, b

   

   Do While Abs(b - a) > 0.000000000000001

      ucSetVariableValue Variable, (a + b) / 2

     

      Value = ucEvaluate(Expression)

     

      If Value = 0 Then a = (a + b) / 2: Exit Do

 

      If Value < 0 _

      Then a = (a + b) / 2 _

      Else b = (a + b) / 2

 

      Iterations = Iterations + 1

      If Iterations = 100 Then Exit Do

   Loop

  

   If Abs(Value) > 0.0000000001 Then ucRaiseErrorMessage Expr, "Solution not found"

 

   ucReturn Expr, a

End Sub

 

This same example is also found in the source code for the demo program for C#, C++ Builder, PB, VB (classic), VB.NET, and VC++.