PC_graph/math_functions.c
2024-12-23 12:27:13 +01:00

96 lines
2.3 KiB
C

#include "math_functions.h"
#include <math.h>
#include <errno.h>
#define MAKE_FUNCTION_1_ARG(name) \
static enum eval_result mf_##name(double *y, const double *args) { \
errno = 0; \
*y = name(args[0]); \
if (errno) \
return EVAL_ERROR; \
return EVAL_OK; \
}
MAKE_FUNCTION_1_ARG(fabs)
MAKE_FUNCTION_1_ARG(exp)
MAKE_FUNCTION_1_ARG(log)
MAKE_FUNCTION_1_ARG(log10)
MAKE_FUNCTION_1_ARG(sin)
MAKE_FUNCTION_1_ARG(cos)
MAKE_FUNCTION_1_ARG(tan)
MAKE_FUNCTION_1_ARG(asin)
MAKE_FUNCTION_1_ARG(acos)
MAKE_FUNCTION_1_ARG(atan)
MAKE_FUNCTION_1_ARG(sinh)
MAKE_FUNCTION_1_ARG(cosh)
MAKE_FUNCTION_1_ARG(tanh)
MAKE_FUNCTION_1_ARG(floor)
MAKE_FUNCTION_1_ARG(ceil)
static double mf_sgn(double *y, const double *args) {
if (args[0] < 0.0)
*y = -1.0;
else if (args[0] > 0.0)
*y = 1.0;
else
*y = 0.0;
return EVAL_OK;
}
static double mf_min(double *y, const double *args) {
if (args[0] < args[1])
*y = args[0];
else
*y = args[1];
return EVAL_OK;
}
static double mf_max(double *y, const double *args) {
if (args[0] > args[1])
*y = args[0];
else
*y = args[1];
return EVAL_OK;
}
static double mf_mod(double *y, const double *args) {
errno = 0;
*y = fmod(args[0], args[1]);
if (errno)
return EVAL_ERROR;
return EVAL_OK;
}
const struct math_function *fns_get(void) {
static const struct math_function fns[] = {
{ "abs", 1, mf_fabs },
{ "exp", 1, mf_exp },
{ "ln", 1, mf_log },
{ "log", 1, mf_log10 },
{ "sin", 1, mf_sin },
{ "cos", 1, mf_cos },
{ "tan", 1, mf_tan },
{ "asin", 1, mf_asin },
{ "acos", 1, mf_acos },
{ "atan", 1, mf_atan },
{ "sinh", 1, mf_sinh },
{ "cosh", 1, mf_cosh },
{ "tanh", 1, mf_tanh },
{ "min", 2, mf_min },
{ "max", 2, mf_max },
{ "mod", 2, mf_mod },
{ "sgn", 1, mf_sgn },
{ "floor", 1, mf_floor },
{ "ceil", 1, mf_ceil },
{ NULL }
};
return fns;
}