// test: echo -e 'prog (1, {set (1, 2), push (arg (1)), show});\ncall (1, 10);\nshow\ndel (1)' | calc.exe -n | grep -q 'stack:$'
// test: echo -e 'prog (1, {set (1, 2), push (arg (1)), show});\ncall (1, 10);\nlen' | calc.exe -n | grep -q '=> 0'
// test: echo -e 'prog (1, {mem (2), sto (1, arg (1) - rcl (1) / 2)})\ncall (1, 1)\ncall (1, 2)\ncall (1, 3)\nprog (1, {mem (2), sto (2, rcl (1)), sto (1, arg (1)), rcl (2)})\ncall (1, 10)' | calc.exe -n | grep -q '=> 2.25'
+// test: echo -e 'set (1, 2, -5, 6, -8, 9, -2, 23, 4)\nord\nshow' | calc.exe | grep -q 'stack: -8 -5 -2 1 2 4 6 9 23'
+// test: echo -e 'set (1, 2, -5, 6, -8, 9, -2, 23, 4)\nmin (5, -3)\nmax (-1)\nmin\nmean\nmed\nmax\nprod\nsum\nvar' | calc.exe | awk 'BEGIN { split("9 -3 -1 -8 3.33333 2 23 -794880 30 73.3333", v) } /=>/ { for (i in v) if ($2 == v[i]) n++ } END { exit n != 10 }'
+// test: echo -e 'min\nmean\nmed\nmax\nprod\nsum\nvar\nord' | calc.exe -n | grep -c error | xargs test 8 =
// Gauss sequence
// test: echo -e '{sto (1, 0), sto (10, 0), while (inc (10) < 100, {sto (1, rcl (1) + rcl (10)), print (rcl (1))})};' | calc.exe | grep -q '=> 5050'
{ "|", Or, 2, 1, -2}
};
-#define NB_FUNCTIONS 42
+#define NB_FUNCTIONS 50
keyword_t functions[NB_FUNCTIONS] = {
{ "sqrt", Sqr, 1, 4, 5},
{ "pow", Pow, 2, 3, 5},
{ "push", Push, 1, 4, 5},
{ "put", Put, 2, 3, 5},
{ "set", Set, MAX_ARGS, 3, 5},
- { "show", Show, 0, 4, 5},
+ { "show", Show, 0, 4, 5},
+ { "max", Max, 2, 3, 5},
+ { "mean", Mean, 2, 4, 5},
+ { "med", Median, 0, 3, 5},
+ { "min", Min, 2, 3, 5},
+ { "ord", Order, 0, 3, 5},
+ { "prod", Prod, 0, 4, 5},
+ { "sum", Sum, 0, 3, 5},
+ { "var", Variance, 2, 3, 5},
};
#define NB_CONSTANTS 3
case Put: func = "Put"; break;
case Set: func = "Set"; break;
case Show: func = "Show"; break;
+ case Max: func = "Maximum"; break;
+ case Mean: func = "Mean"; break;
+ case Median: func = "Median"; break;
+ case Min: func = "Minimum"; break;
+ case Order: func = "Order"; break;
+ case Prod: func = "Product"; break;
+ case Sum: func = "Sum"; break;
+ case Variance: func = "Variance"; break;
}
fprintf (stdout, "Function: %s\n", func);
// free ((programs + n)->string);
//}
- (programs + n)->string = strdup (string);
+ if (string) {
+ (programs + n)->string = strdup (string);
+ }
}
void del (int id)
fprintf (stdout, "\n");
}
+/* stack functions */
+
+double max ()
+{
+ double ret = 0;
+ int i;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ ret = stack[0];
+ for (i = 1; i < stack_size; i++) {
+ if (stack[i] > ret) {
+ ret = stack[i];
+ }
+ }
+ return ret;
+}
+
+double mean ()
+{
+ double ret = 0;
+ int i;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ for (i = 0; i < stack_size; i++) {
+ ret += stack[i];
+ }
+ return ret / stack_size;
+}
+
+double min ()
+{
+ double ret = 0;
+ int i;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ ret = stack[0];
+ for (i = 1; i < stack_size; i++) {
+ if (stack[i] < ret) {
+ ret = stack[i];
+ }
+ }
+ return ret;
+}
+
+void order ()
+{
+ int i, j;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return;
+ }
+ for (i = 0; i < stack_size - 1; i++) {
+ int done = 0;
+ for (j = 0; j < stack_size - 1; j++) {
+ if (stack[j] > stack[j + 1]) {
+ double tmp = stack[j];
+ stack[j] = stack[j + 1];
+ stack[j + 1] = tmp;
+ done = 1;
+ }
+ }
+ if (done == 0) {
+ break;
+ }
+ }
+}
+
+double median ()
+{
+ double ret = 0;
+ if (stack_size < 3) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ double *tmp = (double *) callocordie (stack_size, sizeof (double));
+ memcpy (tmp, stack, stack_size * sizeof (double));
+ order ();
+ ret = stack[(stack_size - 1)/ 2];
+ memcpy (stack, tmp, stack_size * sizeof (double));
+ free (tmp);
+ return ret;
+}
+
+double prod ()
+{
+ double ret = 1;
+ int i;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ for (i = 0; i < stack_size; i++) {
+ ret *= stack[i];
+ }
+ return ret;
+}
+
+double sum ()
+{
+ double ret = 0;
+ int i;
+ if (stack_size < 1) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ for (i = 0; i < stack_size; i++) {
+ ret += stack[i];
+ }
+ return ret;
+}
+
+double variance ()
+{
+ double ret = 0;
+ double m = 0;
+ int i;
+ if (stack_size < 2) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+ return 0;
+ }
+ m = mean ();
+ for (i = 0; i < stack_size; i++) {
+ ret += (stack[i] - m) * (stack[i] - m);
+ }
+ return ret / stack_size;
+}
+
+
/* help message */
void help (void)
fprintf (stdout, " arg call del edit ls prog\n");
fprintf (stdout, "stack management:");
fprintf (stdout, " get len pop push put set show\n");
+ fprintf (stdout, "stack func.:");
+ fprintf (stdout, " max mean med min ord prod sum var\n");
fprintf (stdout, "control management:");
fprintf (stdout, " help quit\n");
fprintf (stdout, "constants:");
case Pop:
case Set:
case Show:
+ case Median:
+ case Order:
+ case Prod:
+ case Sum:
break;
case While:
if (root->ops[0] == NULL) {
}
op1 = (root->ops[1]) ? evaluate_element (root->ops[1], 0) : answer;
break;
+ case Max:
+ case Mean:
+ case Min:
+ case Variance:
+ if (root->ops[0]) {
+ op0 = evaluate_element (root->ops[0], 0);
+ op1 = (root->ops[1]) ? evaluate_element (root->ops[1], 0) : answer;
+ }
}
switch (root->func) {
}
return set (nb, root->ops);
case Show: show (); break;
+ case Max:
+ if (root->ops[0]) {
+ return op0 > op1 ? op0 : op1;
+ }
+ return max ();
+ case Mean:
+ if (root->ops[0]) {
+ return (op0 + op1) / 2;
+ }
+ return mean ();
+ case Median: return median ();
+ case Min:
+ if (root->ops[0]) {
+ return op0 < op1 ? op0 : op1;
+ }
+ return min ();
+ case Order: order (); break;
+ case Prod: return prod ();
+ case Sum: return sum ();
+ case Variance:
+ if (root->ops[0]) {
+ double m = (op0 + op1) / 2;
+ op0 -= m;
+ op1 -= m;
+ return op0 * op0 + op1 * op1;
+ }
+ return variance ();
}
return 0;