5c203edfdd54a0a940be9a0432bf49b14d589d6d
[calc.git] / stack.c
1 #include <malloc.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "alloc.h"
6 #include "debug.h"
7 #include "format.h"
8 #include "parser.h"
9
10 #include "stack.h"
11
12 /* global variables */
13
14 int stack_size = 0;
15 double *stack = NULL;
16
17 /* stack management */
18
19 double get (int n)
20 {
21 double ret = 0;
22 if ((n <= 0) || (n > stack_size)) {
23 VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size));
24 } else {
25 ret = stack[n - 1];
26 }
27 return ret;
28 }
29
30 double length ()
31 {
32 return stack_size;
33 }
34
35 double pop ()
36 {
37 double ret = 0;
38 if (stack_size > 0) {
39 ret = stack[--stack_size];
40 double *tmp = (double *) callocordie (stack_size, sizeof (double));
41 memcpy (tmp, stack, stack_size * sizeof (double));
42 free (stack);
43 stack = tmp;
44 } else {
45 VERBOSE (WARNING, fprintf (stdout, "error stack empty\n"));
46 }
47 return ret;
48 }
49
50 double push (double val)
51 {
52 double *tmp = (double *) callocordie (stack_size + 1, sizeof (double));
53 memcpy (tmp, stack, stack_size * sizeof (double));
54 if (stack) {
55 free (stack);
56 }
57 stack = tmp;
58 stack[stack_size++] = val;
59 return val;
60 }
61
62 double put (int n, double val)
63 {
64 if (n <= 0) {
65 VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size));
66 return 0;
67 }
68 if (n > stack_size) {
69 double *tmp = (double *) callocordie (n, sizeof (double));
70 memcpy (tmp, stack, stack_size * sizeof (double));
71 free (stack);
72 stack = tmp;
73 stack_size = n;
74 }
75 stack[n - 1] = val;
76 return val;
77 }
78
79 double set (int nbops, element_t **ops)
80 {
81 int i;
82 if (stack) {
83 free (stack);
84 }
85 stack = NULL;
86 stack_size = 0;
87 if (nbops != 0) {
88 stack = (double *) callocordie (nbops, sizeof (double));
89 for (i = 0; i < nbops; i++) {
90 stack[i] = evaluate_element (ops[i], 0);
91 }
92 stack_size = nbops;
93 }
94 return stack_size;
95 }
96
97 void show (void)
98 {
99 int i;
100 fprintf (stdout, "stack:");
101 for (i = 0; i < stack_size; i++) {
102 fprintf (stdout, " ");
103 fprintf (stdout, minform, stack[i]);
104 }
105 fprintf (stdout, "\n");
106 }
107
108 /* stack functions */
109
110 double max ()
111 {
112 double ret = 0;
113 int i;
114 if (stack_size < 1) {
115 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
116 return 0;
117 }
118 ret = stack[0];
119 for (i = 1; i < stack_size; i++) {
120 if (stack[i] > ret) {
121 ret = stack[i];
122 }
123 }
124 return ret;
125 }
126
127 double mean ()
128 {
129 double ret = 0;
130 int i;
131 if (stack_size < 1) {
132 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
133 return 0;
134 }
135 for (i = 0; i < stack_size; i++) {
136 ret += stack[i];
137 }
138 return ret / stack_size;
139 }
140
141 double min ()
142 {
143 double ret = 0;
144 int i;
145 if (stack_size < 1) {
146 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
147 return 0;
148 }
149 ret = stack[0];
150 for (i = 1; i < stack_size; i++) {
151 if (stack[i] < ret) {
152 ret = stack[i];
153 }
154 }
155 return ret;
156 }
157
158 void order ()
159 {
160 int i, j;
161 if (stack_size < 1) {
162 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
163 return;
164 }
165 for (i = 0; i < stack_size - 1; i++) {
166 int done = 0;
167 for (j = 0; j < stack_size - 1; j++) {
168 if (stack[j] > stack[j + 1]) {
169 double tmp = stack[j];
170 stack[j] = stack[j + 1];
171 stack[j + 1] = tmp;
172 done = 1;
173 }
174 }
175 if (done == 0) {
176 break;
177 }
178 }
179 }
180
181 double median ()
182 {
183 double ret = 0;
184 if (stack_size < 3) {
185 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
186 return 0;
187 }
188 double *tmp = (double *) callocordie (stack_size, sizeof (double));
189 memcpy (tmp, stack, stack_size * sizeof (double));
190 order ();
191 ret = stack[(stack_size - 1)/ 2];
192 memcpy (stack, tmp, stack_size * sizeof (double));
193 free (tmp);
194 return ret;
195 }
196
197 double prod ()
198 {
199 double ret = 1;
200 int i;
201 if (stack_size < 1) {
202 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
203 return 0;
204 }
205 for (i = 0; i < stack_size; i++) {
206 ret *= stack[i];
207 }
208 return ret;
209 }
210
211 double sum ()
212 {
213 double ret = 0;
214 int i;
215 if (stack_size < 1) {
216 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
217 return 0;
218 }
219 for (i = 0; i < stack_size; i++) {
220 ret += stack[i];
221 }
222 return ret;
223 }
224
225 double variance ()
226 {
227 double ret = 0;
228 double m = 0;
229 int i;
230 if (stack_size < 2) {
231 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
232 return 0;
233 }
234 m = mean ();
235 for (i = 0; i < stack_size; i++) {
236 ret += (stack[i] - m) * (stack[i] - m);
237 }
238 return ret / stack_size;
239 }
240
241 /* vim: set ts=4 sw=4 et: */