missing headers
[calc.git] / stack.c
CommitLineData
a24bd519
LM
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
14int stack_size = 0;
15double *stack = NULL;
16
17/* stack management */
18
19double 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
30double length ()
31{
32 return stack_size;
33}
34
35double 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
50double 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
62double 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
79double 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
97void 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
110double 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
127double 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
141double 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
158void 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
181double 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
197double 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
211double 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
225double 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: */