X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=stack.c;h=829f8aa6483f9357861680931a49a54d0a045799;hb=c91672f948d371d3ba2b1a47db9a31fcabb763f5;hp=5c203edfdd54a0a940be9a0432bf49b14d589d6d;hpb=a24bd5195f9990159a974c98751f1473f29b9fa4;p=calc.git diff --git a/stack.c b/stack.c index 5c203ed..829f8aa 100644 --- a/stack.c +++ b/stack.c @@ -1,106 +1,63 @@ -#include #include -#include -#include "alloc.h" #include "debug.h" #include "format.h" #include "parser.h" +#include "tabular.h" #include "stack.h" /* global variables */ -int stack_size = 0; -double *stack = NULL; +tab_t * stack = NULL; /* stack management */ double get (int n) { - double ret = 0; - if ((n <= 0) || (n > stack_size)) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size)); - } else { - ret = stack[n - 1]; - } - return ret; + return get_tab (stack, n); } double length () { - return stack_size; + return size_tab (stack); } double pop () { - double ret = 0; - if (stack_size > 0) { - ret = stack[--stack_size]; - double *tmp = (double *) callocordie (stack_size, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - free (stack); - stack = tmp; - } else { - VERBOSE (WARNING, fprintf (stdout, "error stack empty\n")); - } - return ret; + return pop_tab (stack, -1); } double push (double val) { - double *tmp = (double *) callocordie (stack_size + 1, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - if (stack) { - free (stack); - } - stack = tmp; - stack[stack_size++] = val; - return val; + return push_tab (stack, -1, val); } double put (int n, double val) { - if (n <= 0) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size)); - return 0; + if (n > size_tab (stack)) { + stack = resize_tab (stack, n); } - if (n > stack_size) { - double *tmp = (double *) callocordie (n, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - free (stack); - stack = tmp; - stack_size = n; - } - stack[n - 1] = val; - return val; + return set_tab (stack, n, val); } double set (int nbops, element_t **ops) { int i; - if (stack) { - free (stack); - } - stack = NULL; - stack_size = 0; - if (nbops != 0) { - stack = (double *) callocordie (nbops, sizeof (double)); - for (i = 0; i < nbops; i++) { - stack[i] = evaluate_element (ops[i], 0); - } - stack_size = nbops; - } - return stack_size; + stack = resize_tab (stack, nbops); + for (i = 0; i < nbops; i++) { + set_tab (stack, i + 1, evaluate_element (ops[i], 0)); + } + return size_tab (stack); } void show (void) { - int i; + int i, n = size_tab (stack); fprintf (stdout, "stack:"); - for (i = 0; i < stack_size; i++) { + for (i = 0; i < n; i++) { fprintf (stdout, " "); - fprintf (stdout, minform, stack[i]); + fprintf (stdout, minform, get_tab (stack, i + 1)); } fprintf (stdout, "\n"); } @@ -110,15 +67,16 @@ void show (void) 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)); + int i, n = size_tab (stack); + if (n < 1) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - ret = stack[0]; - for (i = 1; i < stack_size; i++) { - if (stack[i] > ret) { - ret = stack[i]; + ret = get_tab (stack, 1); + for (i = 1; i < n; i++) { + double cur = get_tab (stack, i + 1); + if (cur > ret) { + ret = cur; } } return ret; @@ -127,29 +85,30 @@ double max () 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)); + int i, n = size_tab (stack); + if (n < 1) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - for (i = 0; i < stack_size; i++) { - ret += stack[i]; + for (i = 0; i < n; i++) { + ret += get_tab (stack, i + 1); } - return ret / stack_size; + return ret / n; } 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)); + int i, n = size_tab (stack); + if (n < 1) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - ret = stack[0]; - for (i = 1; i < stack_size; i++) { - if (stack[i] < ret) { - ret = stack[i]; + ret = get_tab (stack, 1); + for (i = 1; i < n; i++) { + double cur = get_tab (stack, i + 1); + if (cur < ret) { + ret = cur; } } return ret; @@ -157,53 +116,39 @@ double min () 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; - } + int n = size_tab (stack); + if (n < 3) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); + } else { + order_tab (stack); } } 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; + int n = size_tab (stack); + if (n < 3) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); + } else { + tab_t *tmp = copy_tab (stack); + order_tab (tmp); + ret = get_tab (tmp, (n - 1) / 2 + 1); + free_tab (tmp); } - 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)); + int i, n = size_tab (stack); + if (n < 1) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - for (i = 0; i < stack_size; i++) { - ret *= stack[i]; + for (i = 0; i < n; i++) { + ret *= get_tab (stack, i + 1); } return ret; } @@ -211,13 +156,13 @@ double prod () 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)); + int i, n = size_tab (stack); + if (n < 1) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - for (i = 0; i < stack_size; i++) { - ret += stack[i]; + for (i = 0; i < n; i++) { + ret += get_tab (stack, i + 1); } return ret; } @@ -225,17 +170,17 @@ double sum () 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)); + int i, n = size_tab (stack); + if (n < 2) { + VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n)); return 0; } - m = mean (); - for (i = 0; i < stack_size; i++) { - ret += (stack[i] - m) * (stack[i] - m); + double m = mean (); + for (i = 0; i < n; i++) { + double x = get_tab (stack, i + 1); + ret += (x - m) * (x - m); } - return ret / stack_size; + return ret / n; } /* vim: set ts=4 sw=4 et: */