Calculator/calculator.cpp

87 lines
2.5 KiB
C++
Raw Normal View History

2023-11-26 15:56:00 +01:00
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "calculator.h"
double str_to_double (const char * str) {
return strtod (str, NULL);
}
long str_to_long (const char * str) {
return strtol (str, NULL, 10);
}
static double u_minus (const double x) { return -x; }
const unary_function unary_function_table [UNARY_max] = {
u_minus,
sin, cos, exp, log,
};
static double b_plus (const double a, const double b) { return a + b; }
static double b_minus (const double a, const double b) { return a - b; }
static double b_multiply (const double a, const double b) { return a * b; }
static double b_divide (const double a, const double b) { return b !=0.0 ? a / b : 1.0; }
const binary_function binary_function_table [BINARY_max] = {
b_plus, b_minus, b_multiply, b_divide, pow,
};
static CommonData * main_data = nullptr;
void addVariable (const char * str, const double x) {
printf ("\"%s\"\t= %g\n", str, x);
if (main_data->list == nullptr) {
main_data->list = new VariableList (str, x);
return;
}
main_data->list->add(str, x);
}
void addRange (const char * str, const double x, const double e, const double s) {
printf ("\"%s\"\t= [%g:%g],%g\n", str, x, e, s);
if (main_data->list == nullptr) {
main_data->list = new VariableList (str, x, e, s);
return;
}
main_data->list->add(str, x, e, s);
}
static Range zero = {0.0, 0.0, 0.0};
Variable::Variable(const char * name) {
data = main_data->list->find (name);
if (!data) {
printf("variable \"%s\" not assigned, zero used\n", name);
data = & zero;
}
}
2023-11-27 15:14:06 +01:00
static bool first = false;
extern void emitData (double * x, double * y, const int len, const bool first);
2023-11-26 15:56:00 +01:00
void addExpression (Expression * e) {
if (main_data->root) delete main_data->root;
main_data->root = e;
VariableList * vl = main_data->list->find_ranged();
if (!vl) {
printf("f() = %g\n", e->eval());
return;
}
Range * r = vl->get();
const double x0 = r->value, x1 = r->end, s = fabs (r->step);
int n = (x1 - x0) / s;
if (n <= 0) return;
double * vx = new double [n + 1];
double * vy = new double [n + 1];
for (int i=0; i<n+1; i++) {
const double x = x0 + (double) i * s;
r->value = x;
const double y = e->eval();
vx[i] = x; vy[i] = y;
}
2023-11-27 15:14:06 +01:00
r->value = x0;
// printf("add expression first=%d, n=%d\n", (int) first, n);
emitData (vx, vy, n+1, first);
if (first) first = false;
2023-11-26 15:56:00 +01:00
delete [] vx; delete [] vy;
}
void initData () {
2023-11-27 15:14:06 +01:00
first = true;
2023-11-26 15:56:00 +01:00
main_data = new CommonData();
}
void finiData () {
delete main_data;
}