# B4A LibraryExpressionEvaluator library

I've been meaning to do this for my own use for a while and I have finally got a round tuit that allowed me to get on with it. Everyone should have a round tuit - they are so useful!

This is the recursive descent parser from my BasicLib library stripped down to deal with arithmetic functions only. Pass it a valid arithmetic expression as a string and it will return the result. Use a help viewer to see what is supported but basically it will evaluate any arithmetic expression that Basic4android can. It also supports variables that may be used to pass values and store intermediate results.

EDIT :- Version 1.1 has improved error reporting. See post #3 for details.

#### Attachments

• aroundtuit.jpg
23 KB · Views: 820
• ExpressionEvaluator1.1.zip
15.3 KB · Views: 1,568
Last edited:

#### agraham

##### Expert
Longtime User
I realised that with a trivial reorganisation of part of the code I could provide better error handling without impacting performance by adding extra checks.

Version 1.1 now posted should hopefully give a sensible understandable error message under all circumstances. If it doesn't then please post the expression that breaks it and I'll fix it.

#### Informatix

##### Expert
Longtime User
Thanks for this library. It's very useful.
In my new project, I'd need two more functions: CEIL(n) and DICE(number,sides). Could you add it? DICE could be coded like this:
B4X:
``````   // r = number of dice, s = sides
int result = 0;
for (int i=0; i < r; i++) {
result = result + Math.floor((Math.random() * s) + 1);
}``````

#### tonyp

##### Member
Longtime User
Division by zero gives no error.

Division by zero gives "Infinity", but no errors.

Since there is no error, how do I test for infinity so I can report an ERROR?

(And I consider it more appropriate that division by zero gives an error, as Infinity is more like an answer for LIMITS, e.g., division by a value as it approaches zero.)

TIA

To test:
B4X:
``````Dim e As Evaluator
Dim ans As Double
e.Initialize
e.SetGlobal("x",0)
ans = e.Evaluate("1/x")
Log("Error Message: " & e.Error)
Log("Error Flag   : " & e.ErrorFlag)

#### agraham

##### Expert
Longtime User
This is what Java does for floating point division. It does not throw exceptions or errors. The behaviour of Basic4android code is the same. You can test against the string "Infinity"
B4X:
``Log(ans = "Infinity")``
The other possibilities are "-Infinity" and "NaN".

•1/0 yields Infinity.
•(-1)/0 yields -Infinity.
•0/0 yields NaN.

Java would throw exceptions if this were done for integer values but interestingly Basic4android doesn't as it seem to promote some or all integer operations to floating point. I have queried this with Erel.

#### tonyp

##### Member
Longtime User
OK, it works. Thanks.

I realized I can also compare to 1/0
B4X:
``if ans = 1/0 then ...``

or, all possibilities:

B4X:
``if (ans = 1/0) or (ans = (-1)/0) or (ans = 0/0) then ... error``

I suppose this comparison could also be done inside the library and an error set, accordingly.
(Unless you can think of a reason why this would not be required at all times.)

Last edited:

#### agraham

##### Expert
Longtime User
The Java behaviour is by design. As it is running in a Java environment I conform to that design.

#### JLS

##### Member
Longtime User
Hello everybody.

I have detected that sometimes the answer it's a little bit unaccurate. For example:

e.Evaluate("3*3") returns 9 (it´s OK)
e.Evaluate("0.03*3) returns 0.09 (it's OK)
e.Evaluate("0.03*3) returns 0.8999999999999 (????)

Can somebody tell me why this happens and how to fix?

Thanks a lot

#### Erel

##### B4X founder
Staff member
Longtime User
Binary floating point numeric systems cannot accurately represent decimal numbers. You need to use NumberFormat when you display the number.

#### JLS

##### Member
Longtime User
Thank you very much, Erel. I'm following this way and now it Works fine.

It's hard at the beginning.

Thanks again.

#### Fusseldieb

##### Active Member
Longtime User
I have a little problem with your library. The variable "I" returns everytime a diferent value.

Example, I resolve the 3x3 matrix:

First, I set the variables:
B4X:
``````Eval.SetGlobal("A",1)
Eval.SetGlobal("B",1)
Eval.SetGlobal("C",1)
Eval.SetGlobal("D",1)
Eval.SetGlobal("E",1)
Eval.SetGlobal("F",1)
Eval.SetGlobal("G",1)
Eval.SetGlobal("H",1)
Eval.SetGlobal("I",1)``````

A B C
D E F
G H I

Then, the value goes to:
1 1 1
1 1 1
1 1 3

And everytime I call variable "I", the value increases +1...

I don't know why...

(Other variables doesn't make that mess)

EDIT: Sorry, the fail was on my side. Nevermind

For those who want to know too: I have declared variable "I" later in the code too
B4X:
``For i=0 To.....``
And THAT make the mess

Last edited:

#### imbault

##### Well-Known Member
Longtime User
I've been meaning to do this for my own use for a while and I have finally got a round tuit that allowed me to get on with it. Everyone should have a round tuit - they are so useful!

This is the recursive descent parser from my BasicLib library stripped down to deal with arithmetic functions only. Pass it a valid arithmetic expression as a string and it will return the result. Use a help viewer to see what is supported but basically it will evaluate any arithmetic expression that Basic4android can. It also supports variables that may be used to pass values and store intermediate results.

EDIT :- Version 1.1 has improved error reporting. See post #3 for details.

Hi Agraham, is it possible to add IIF(,,), in your library, I'm OK to pay for this functionality, just tell me, if it's possible and then how much

My best regards

Patrick

#### imbault

##### Well-Known Member
Longtime User
@agraham , another option, if you please, is to share source code of your library, in order to add other functions

Anyway, thanks for this library

Patrick

#### MaFu

##### Well-Known Member
Longtime User
@agraham , another option, if you please, is to share source code of your library, in order to add other functions

Anyway, thanks for this library

Patrick
Have a look on the math parser of my MFLib. With this you can create user defined functions.
Example:
B4X:
``````...
MF_MathParser.CreateUserFunction("test", 2, "TestEvent"))
MF_MathParser.Parse("test(5,7)"))
...

Sub TestEvent_Calc(name As String, values() As Double) As Double
Dim result As Double = 0.0
For Each v In values
result = result + v
Next
Return result
End Sub``````

#### imbault

##### Well-Known Member
Longtime User
Thanks, it looks interesting, I didn't know you made that lib

#### stanmiller

##### Active Member
Longtime User
Hi Agraham, is it possible to add IIF(,,), in your library, I'm OK to pay for this functionality, just tell me, if it's possible and then how much

My best regards

Patrick

It's possible. Did you still need this?

Are you looking for the old dBase/Clipper IIF() ?

http://www.ousob.com/ng/sum87/ng175f6.php

#### imbault

##### Well-Known Member
Longtime User
Hi, yes, correct I need this IIF function, any idea?
Thanks

#### MaFu

##### Well-Known Member
Longtime User
It's possible. Did you still need this?

Are you looking for the old dBase/Clipper IIF() ?

http://www.ousob.com/ng/sum87/ng175f6.php

No, he didn't. He's now using my MFLib.

Maybe dBase was the grandfather of IIF, but now many modern languages included this function.

Replies
1
Views
2K
Replies
168
Views
30K
Replies
51
Views
8K
Replies
4
Views
2K
Replies
4
Views
4K