83 lines
2.4 KiB
C++
83 lines
2.4 KiB
C++
|
#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;
|
||
|
}
|
||
|
}
|
||
|
extern void emitData (double * x, double * y, const int len);
|
||
|
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];
|
||
|
// printf("n=%d\n", n);
|
||
|
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;
|
||
|
}
|
||
|
emitData (vx, vy, n+1);
|
||
|
delete [] vx; delete [] vy;
|
||
|
}
|
||
|
void initData () {
|
||
|
main_data = new CommonData();
|
||
|
}
|
||
|
void finiData () {
|
||
|
delete main_data;
|
||
|
}
|
||
|
|