SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Filterscripts > Includes

Reply
 
Thread Tools Display Modes
Old 02/02/2012, 09:58 PM   #1
RyDeR`
High-roller
 
RyDeR`'s Avatar
 
Join Date: Feb 2009
Location: Belgium
Posts: 2,929
Reputation: 700
Default MathParser.inc ─ Advanced mathematical expression parser

Introduction

It has been quite a while since I last released something as I was running out of ideas and didn't know what to script nor program, but luckily, ****** PM'ed me about some useful ideas and finally picked this one out. This include simply parses mathematical expressions in a correct way. You can dynamically add your own operators, constants and functions as you wish. More examples and features below.

Functions

Here's a quick list of the main functions you can use:
pawn Code:
stock Float: Math::ParseExpression(szExpr[], &e_Error: iError = ERROR_NONE, &iIdx = 0, const iSize = sizeof(szExpr));
stock Math::AddFunction(const szName[], const szFunc[], const iParams);
stock Math::RemoveFunction(const szName[]);
stock Math::AddConstant(const szConst[], const Float: fValue);
stock Math::RemoveConstant(const szConst[]);
stock Math::AddOperator(const szOp[], const szFunc[], const iPrecedence, const e_Assoc: iAssoc);
stock Math::RemoveOperator(const szOp[]);

A list of the defines:
pawn Code:
#if !defined PRECISION
    #define PRECISION 3
#endif

#define MAX_OPERATORS (32)
#define MAX_OPERATOR_LENGTH (8)
#define MAX_OPERATOR_FUNCTION_LENGTH (20)

#define MAX_CONSTANTS (32)
#define MAX_CONSTANT_LENGTH (20)

#define MAX_FUNCTIONS (32)
#define MAX_FUNCTION_LENGTH (16)
#define MAX_FUNCTION_FUNCTION_LENGTH (20)
#define MAX_FUNCTION_PARAMS (8)
#define MAX_FUNCTION_PARAMS_LENGTH (32)
If you define PRECISION before this include, you can have your own decimal precision value instead.

And the error types:
pawn Code:
enum e_Error {
    ERROR_NONE,
    ERROR_LOGICAL_VALUE,
    ERROR_LOGICAL_OPERATOR,
    ERROR_LOGICAL_PARANTHESES,
    ERROR_PARAMETER_FUNCTION
};

Examples

Basic examples

First of all, the following operators, constants and functions are pre-added:
pawn Code:
Math::AddOperator("E", "E", 25, RIGHT_TO_LEFT);
Math::AddOperator("^", "Pow", 20, RIGHT_TO_LEFT);
Math::AddOperator("*", "Mul", 15, LEFT_TO_RIGHT);
Math::AddOperator("/", "Div", 15, LEFT_TO_RIGHT);
Math::AddOperator("%", "Mod", 15, LEFT_TO_RIGHT);
Math::AddOperator("+", "Add", 10, LEFT_TO_RIGHT);
Math::AddOperator("-", "Sub", 10, LEFT_TO_RIGHT);
               
Math::AddConstant("pi", 3.141592);
Math::AddConstant("e", 2.718281);
               
Math::AddFunction("log", "Log", 2);
Math::AddFunction("sqrt", "Sqrt", 1);

Let's start with a simple example:
pawn Code:
new
    szExpr[128] = "3 + 0x4 * 0x2 / (1 - 0b00000101) ^ 2 ^ 3"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print Solution: 3.000. PRECISION decides the amount of numbers after the comma which is 3 in this case. Please note you can also use hexadecimal and binary notation.

Example with the pre-added function(s):
pawn Code:
new
    szExpr[128] = "log(32, 2.0)"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print 5.000.

We can also use constants and expressions in our function parameters:
pawn Code:
new
    szExpr[128] = "(sqrt(log(32.0, 2.0) - 1) ^ 2 ^ 3) * 4"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print 1024.000.

Let's use some constants:
pawn Code:
new
    szExpr[128] = "e ^ pi"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Is the same as 2.718 ^ 3.141 and results 23.119.

And some other examples:
pawn Code:
new
    szExpr[128] = "((3 * (2 * (sqrt(25) + log(0x2000, 2.0) + 3) * 3 ^ (3 % 2))) / 0b00100000 * e)"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print 32.106

pawn Code:
new
    szExpr[128] = "5E+6 + 20.556"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print 5000020.500 (rounded)

How to customize?

It's very easy to define your own operators, functions or constants. Let's start with the operator:
pawn Code:
Math::AddOperator("<<", "SHL", 5, LEFT_TO_RIGHT); // To be called before parsing (ex. OnGameModeInit)

Math::Operator SHL(const Float: fValue1, const Float: fValue2) { // To be added somewhere in your script
    return float(floatround(fValue1) << floatround(fValue2));
}
You might be wondering like "what the hell are those parameters for"? The answer is quite simple, each operator has its own precedence and associativity. I usually look here for the data I need, but as you may have noticed, the precedences are a bit different. I just use them in reverse order with other values (as the value doesn't really matter, just make sure it's bigger or smaller).

pawn Code:
Math::AddFunction("dist", "Dist", 4); // To be called before parsing (ex. OnGameModeInit)

Math::Function Dist(const Float: fX1, const Float: fX2, const Float: fY1, const Float: fY2) { // To be added somewhere in your script
    return floatsqroot(floatpower(fX1 - fX2, 2.0) + floatpower(fY1 - fY2, 2.0));
}
This one is quite obvious I guess. In the first parameter you add the name you want to use in your expression, the second one the function to call, in the last parameter the number of parameters the function has.

pawn Code:
Math::AddConstant("MAX_PLAYERS", MAX_PLAYERS); // To be added somewhere in your script
Same here. In the first parameter the name you want to use in your expression and in the second one the value of it.

Let's use them all:
pawn Code:
new
    szExpr[128] = "(dist(5, -9, pi, e) << 10) / MAX_PLAYERS"
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
Will print us 28.672 when you consider MAX_PLAYERS to be 500.

What if I enter an invalid expression?

The answer is simple, the iError variable will change from ERROR_NONE to an error index from e_Error. You can retrieve the error index by adding a second parameter to Math::ParseExpression. Example:
pawn Code:
new
    szExpr[128] = "5 + 5 + ",
    e_Error: iError
;
printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr, iError));
Will set iError to ERROR_LOGICAL_VALUE in this case because you don't have any value added after the + operator.

Download

MathParser.inc

Changelog
  • 02/02/2011 ─ v0.1.0:
    • Initial release
  • 04/02/2011 ─ v0.1.0:
    • Fixes:
      • Bug regarding decimal and hexadecimal values.
    • Removes:
      • The E (scientific notation) function is removed and is replaced with an operator instead.
      • A small, unnecessary debugging code.
    • Adds:
      • Due to this bugfix, it is now possible to use E (scientific notation) as an operator which means you can now use this syntax:
        pawn Code:
        new
            szExpr[128] = "5E-3"
        ;
        printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
        Will print us 0.005.

        pawn Code:
        new
            szExpr[128] = "5.5128E+5"
        ;
        printf("Solution: %." #PRECISION "f", Math::ParseExpression(szExpr));
        And this will print us 551280.000

Notes

I'm not sure if I explained everything, but this is pretty much it. This include may contains bugs so please report if you find one. Also please note to allocate enough cells in your szExpr string-array containing your expression in case it replaces (functions, constants) and the length becomes something longer than the total size of your expression string.
__________________

Sup?

Last edited by RyDeR`; 04/02/2012 at 05:56 PM.
RyDeR` is offline   Reply With Quote
Old 02/02/2012, 10:00 PM   #2
BlackBank
Gangsta
 
Join Date: Dec 2010
Location: The Netherlands
Posts: 523
Reputation: 437
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Wow, very nice and usefull!
BlackBank is offline   Reply With Quote
Old 02/02/2012, 10:11 PM   #3
FireCat
High-roller
 
FireCat's Avatar
 
Join Date: Jul 2010
Posts: 2,322
Reputation: 609
Default Re: MathParser.inc ─ Advanced mathematical expression parser

This, actually looks helpfull (:
FireCat is offline   Reply With Quote
Old 02/02/2012, 10:23 PM   #4
[DOG]irinel1996
High-roller
 
[DOG]irinel1996's Avatar
 
Join Date: Jan 2010
Posts: 1,470
Reputation: 288
Default Respuesta: MathParser.inc ─ Advanced mathematical expression parser

RyDeR`always amazes me. 5/5
Awesome, no comments...
[DOG]irinel1996 is offline   Reply With Quote
Old 02/02/2012, 10:26 PM   #5
SlashPT
High-roller
 
SlashPT's Avatar
 
Join Date: Sep 2009
Location: Hell
Posts: 1,973
Reputation: 116
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Actually I won't use it... but anyways the script looks very clean and nice, I like it....

Very nice work, keep it up
__________________

Zh3r0Jansish
SlashPT is offline   Reply With Quote
Old 03/02/2012, 11:14 AM   #6
Lorenc_
High-roller
 
Lorenc_'s Avatar
 
Join Date: Jan 2010
Location: Australia
Posts: 3,798
Reputation: 1174
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Very nice release RyDeR`!
__________________
Join the best Cops And Robbers in SA-MP, today. svr.sfcnr.com:7777

Lorenc_ is offline   Reply With Quote
Old 03/02/2012, 12:05 PM   #7
RyDeR`
High-roller
 
RyDeR`'s Avatar
 
Join Date: Feb 2009
Location: Belgium
Posts: 2,929
Reputation: 700
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Thanks! I'm open for suggestions and improvements, so if there are any, let me know.
__________________

Sup?
RyDeR` is offline   Reply With Quote
Old 03/02/2012, 02:31 PM   #8
-ExG-VirusKiller
Little Clucker
 
Join Date: Jan 2012
Posts: 43
Reputation: 6
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Again a great release from you RyDeR`
-ExG-VirusKiller is offline   Reply With Quote
Old 03/02/2012, 02:40 PM   #9
Slice
High-roller
 
Join Date: Mar 2008
Posts: 1,831
Reputation: 1607
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Nice!
Slice is offline   Reply With Quote
Old 03/02/2012, 08:50 PM   #10
RyDeR`
High-roller
 
RyDeR`'s Avatar
 
Join Date: Feb 2009
Location: Belgium
Posts: 2,929
Reputation: 700
Default Re: MathParser.inc ─ Advanced mathematical expression parser

Thanks - glad you liked it!
__________________

Sup?
RyDeR` is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Tool/Web/Other] [PHP] SA-MP Website Banlist Parser iLinx Tools and Files 57 21/08/2014 10:33 AM
Mathematical functions? knackworst Scripting Help 5 05/10/2011 06:32 AM
[Tool/Web/Other] Include file parser Slice Tools and Files 3 15/09/2011 09:05 AM
PAWN code parser Torekk Everything and Nothing 1 10/10/2010 10:39 PM
Mathematical Problem! Who can help me out? Sandra18[NL] Help Archive 5 13/03/2009 11:52 PM


All times are GMT. The time now is 12:09 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.