-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcexp-lib.cc
More file actions
135 lines (121 loc) · 3.5 KB
/
cexp-lib.cc
File metadata and controls
135 lines (121 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* C Expression Evaluator -- Additional mathematics functions
*
* This program is distributed under the terms of the GPL v3.0 or later
* Download the GNU Public License (GPL) from <https://www.gnu.org>
*
* Copyright(C) 2025, Free Software Foundation, Inc.
* Written by Nicholas Christopoulos <mailto:netnic@proton.me>
*/
// sign (returns 1 0 -1)
static real_t sgn(real_t x) {
if ( x > 0 ) return 1;
if ( x < 0 ) return -1;
return 0;
}
// deg 2 rad
static real_t rad(real_t x) { return x * (M_PI / 180.0); }
// rad 2 deg
static real_t deg(real_t x) { return x * (180.0 / M_PI); }
// if(expr,true,false)
static int iff(const vector<CVar>& args, CVar *result) {
if ( args.size() != 3 ) throw runtime_error("iff(): wrong number of parameters");
if ( args[0].getf() )
result->setf(args[1].getf());
else
result->setf(args[2].getf());
return 0;
}
// RND, random number generator
static real_t rnd(real_t x) {
ssize_t lo = 0, hi = x;
return round(lo + (hi - lo) * rand() / RAND_MAX);
}
// INV, inverse matrix
static int inv(const vector<CVar>& args, CVar *result) {
if ( args.size() != 1 ) throw runtime_error("inv(): wrong number of parameters");
result->setm(args[0].getm().inverse());
return 0;
}
// T, transpose matrix
static int transp(const vector<CVar>& args, CVar *result) {
if ( args.size() != 1 ) throw runtime_error("t(): wrong number of parameters");
result->setm(args[0].getm().transpose());
return 0;
}
// I, identity matrix
static int identity(const vector<CVar>& args, CVar *result) {
if ( args.size() != 1 ) throw runtime_error("i(): wrong number of parameters");
result->setm(args[0].getm().identity());
return 0;
}
// det, matrix, determinant
static int det(const vector<CVar>& args, CVar *result) {
if ( args.size() != 1 ) throw runtime_error("det(): wrong number of parameters");
result->setf(args[0].getm().determinant());
return 0;
}
/* -- test unlimited parameters -- */
// vmax, max(...)
static int vmax(const vector<CVar>& args, CVar *result) {
if ( args.size() > 0 ) {
real_t xmax = args[0].getf();
for ( size_t i = 1; i < args.size(); i ++ )
if ( args[i].getf() > xmax )
xmax = args[i].getf();
result->setf(xmax);
return 0;
}
throw runtime_error("max(): no value specified");
}
// vmin, min(...)
static int vmin(const vector<CVar>& args, CVar *result) {
if ( args.size() > 0 ) {
real_t xmin = args[0].getf();
for ( size_t i = 1; i < args.size(); i ++ )
if ( args[i].getf() < xmin )
xmin = args[i].getf();
result->setf(xmin);
return 0;
}
throw runtime_error("no value specified");
}
// printf(...)
static int pf(const vector<CVar>& args, CVar *result) {
if ( args.size() > 0 ) {
const char *p = args[0].gets().c_str();
size_t pos = 0;
char buf[256], *t = buf;
char fmt[16], *f = fmt;
int count;
while ( *p ) {
if ( *p == '%' && *(p+1) == '%' ) {
p += 2; *t ++ = '%';
continue;
}
else if ( *p == '%' ) {
f = fmt;
while ( *p ) {
*f ++ = *p ++;
if ( strchr("sSfFgGeEdiXxu", *(p-1)) != NULL ) break;
if ( (f - fmt) == 15 ) break;
}
*f = '\0';
if ( toupper(*(p-1)) == 'S' )
count = sprintf(t, fmt, args[++ pos].gets());
else if ( toupper(*(p-1)) == 'F' || toupper(*(p-1)) == 'E' || toupper(*(p-1)) == 'G' )
count = sprintf(t, fmt, args[++ pos].getf());
else
count = sprintf(t, fmt, args[++ pos].geti());
if ( count > 0 )
t += count;
continue;
}
*t ++ = *p ++;
}
*t = '\0';
result->sets(buf);
return 0;
}
throw runtime_error("no format specified");
}