mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 16:56:42 +08:00
118 lines
4.4 KiB
Markdown
118 lines
4.4 KiB
Markdown
## Introduction
|
|
|
|
This module is a simple parser and calculator for mathematical expressions. By passing in a simple arithmetic expression, it calculates the result.
|
|
|
|
## Interface
|
|
|
|
### Expression Calculation
|
|
```c
|
|
double calculate(const char *expression);
|
|
```
|
|
This function is very simple to use: pass in the expression, and it returns the calculation result. The default return type is double precision floating-point, which has a wide range and is suitable for floating-point calculations. When there is a calculation error, it returns `NAN`.
|
|
The supported operators include: addition `+`, subtraction `-`, multiplication `*`, division `/`, exponentiation `^`, and modulus `%`. The operator precedence is as follows:
|
|
| Operator | Precedence |
|
|
|:--------:|:----------:|
|
|
| ^ | 0 |
|
|
| * / % | 1 |
|
|
| + - | 2 |
|
|
|
|
In addition to basic arithmetic operations, built-in functions are also supported. The function name is followed by `()`, where the function parameters are passed inside the parentheses, and multiple parameters are separated by commas `,`.
|
|
| Function | Parameters | Description |
|
|
|:----------:|:-----------:|:-------------:|
|
|
| abs | 1 | Absolute value |
|
|
| sqrt | 1 | Square root |
|
|
| exp | 1 | Natural exponential |
|
|
| ln | 1 | Natural logarithm |
|
|
| sin | 1 | Sine |
|
|
| cos | 1 | Cosine |
|
|
| tan | 1 | Tangent |
|
|
| cot | 1 | Cotangent |
|
|
| asin | 1 | Arcsine |
|
|
| acos | 1 | Arccosine |
|
|
| atan | 1 | Arctangent |
|
|
| acot | 1 | Arccotangent |
|
|
| ceil | 1 | Ceiling |
|
|
| floor | 1 | Floor |
|
|
| min | 2 | Minimum of two |
|
|
| max | 2 | Maximum of two |
|
|
| pow | 2 | Power function, same as `^` |
|
|
| log | 2 | Logarithm function |
|
|
|
|
Additionally, there are constants `pi` and `e`, which are case-insensitive.
|
|
Spaces may be retained between operators and numbers for clarity, **but numbers must be tightly combined into a single number**.
|
|
|
|
Simple examples:
|
|
```c
|
|
static void test_base(void)
|
|
{
|
|
const char *expression[] = {
|
|
" ( 99 * 3 ) ",
|
|
" min (12, 3)",
|
|
"sin ( 11 / 2 * pi ) + 100 ",
|
|
};
|
|
|
|
for (int i = 0; i < sizeof(expression) / sizeof(expression[0]); i++)
|
|
{
|
|
printf("cal: %s = %lf\r\n", expression[i], calculate(expression[i]));
|
|
}
|
|
}
|
|
```
|
|
Calculation results:
|
|
```
|
|
cal: ( 99 * 3 ) = 297.000000
|
|
cal: min (12, 3) = 3.000000
|
|
cal: sin ( 11 / 2 * Pi ) + 100 = 99.000000
|
|
```
|
|
|
|
You can export this calculation module as a command to execute calculations in command form. This command function has already removed unnecessary trailing zeros after the decimal point for a more aesthetically pleasing display.
|
|
```c
|
|
static int command_calculate(const char *expression)
|
|
{
|
|
double r = NAN;
|
|
if (!expression) return 0;
|
|
r = calculate(expression);
|
|
if (fabs(floor(r) - r) <= DBL_EPSILON && fabs(r) < 1.0e60) printf("%.0lf\r\n", r);
|
|
else if (fabs(r) < 1.0e-6 || fabs(r) > 1.0e9) printf("%e\r\n", r);
|
|
else
|
|
{
|
|
char p[64];
|
|
int len = 0;
|
|
len = sprintf(p, "%lf", r);
|
|
while (len > 0 && p[len-1] == '0' && p[len-2] != '.') {p[--len] = 0;}
|
|
printf("%s\r\n", p);
|
|
}
|
|
return 1;
|
|
}
|
|
```
|
|
Input command:
|
|
```
|
|
calculate -c "sin( 11 / 2 * Pi ) + 2 ^ 3"
|
|
```
|
|
Calculation result:
|
|
```
|
|
7
|
|
```
|
|
|
|
### Exporting
|
|
|
|
```c
|
|
int calculate_function(const char *name, double (*func)(), int argc); // Export function
|
|
int calculate_constant(const char *name, double value); // Export constant
|
|
```
|
|
|
|
These two methods export functions and constants, respectively.
|
|
|
|
To export a function, you pass in the function name, function pointer, and the number of parameters. It supports exporting up to `CALCULATE_EXFUNC_MAX` functions.
|
|
|
|
To export a constant, you pass in the constant name and constant value, supporting up to `CALCULATE_CONSTV_MAX` constants.
|
|
|
|
### List Key Identifiers
|
|
|
|
```c
|
|
const char* calculate_ls_func(int *argc); // List functions
|
|
const char* calculate_ls_const(double *value); // List constants
|
|
```
|
|
|
|
These two methods list functions and constants, respectively.
|
|
|
|
Both use an iterative list method that continues until `NULL` is returned. |