04-median.c - libzahl - big integer library
 (HTM) git clone git://git.suckless.org/libzahl
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       04-median.c (1167B)
       ---
            1 /* Calculates the median of $@ */
            2 
            3 #include <stdio.h>
            4 #include <stdlib.h>
            5 
            6 #include <zahl.h>
            7 
            8 int
            9 main(int argc, char *argv[])
           10 {
           11         struct zahl *values;
           12         z_t med, medmod;
           13         jmp_buf env;
           14         char *buf, *argv0;
           15         int i, j;
           16 
           17         argv0 = *argv++, argc--;
           18 
           19         if (!argc) {
           20                 fprintf(stderr,
           21                         "%s: cannot calculate median of the empty bag\n",
           22                         argv0);
           23                 return 1;
           24         }
           25 
           26         values = calloc(argc, sizeof(*values));
           27         if (!values)
           28                 return perror(argv0), 1;
           29 
           30         if (setjmp(env))
           31                 return zperror(argv0), 1;
           32 
           33         zsetup(env);
           34         zinit(med);
           35         zinit(medmod);
           36 
           37         /* Since `values` where allocated with
           38          * `calloc` it is already cleared and
           39          * `zinit` is not necessary. */
           40 
           41         for (i = 0; i < argc; i++)
           42                 zsets(&values[i], argv[i]);
           43 
           44         qsort(values, argc, sizeof(*values),
           45               (int (*)(const void *, const void *))zcmp);
           46         i = argc / 2;
           47         j = i - !(argc & 1);
           48         zadd(med, &values[i], &values[j]);
           49         zsetu(medmod, 2);
           50         zdivmod(med, medmod, med, medmod);
           51 
           52         printf("%s%s\n", buf = zstr(med, NULL, 0),
           53                        (const char *[]){"", ".5"}[zodd(medmod)]);
           54         free(buf);
           55 
           56         zfree(medmod);
           57         zfree(med);
           58         for (i = 0; i < argc; i++)
           59                 zfree(&values[i]);
           60         free(values);
           61         zunsetup();
           62         return 0;
           63 }