Annotation of coherent/d/bin/bc/putnum.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include "bc.h"
                      3: 
                      4: 
                      5: /*
                      6:  *     The current output base is encoded in several variables.
                      7:  *     If every digit in the base can be represented by a single
                      8:  *     char (ie. outbase <= maxsobase) then smallbase is TRUE and
                      9:  *     obase contains the output base.  If not then smallbase is
                     10:  *     FALSE and obase contains 10.  In any case, outbase contains
                     11:  *     the current output base.
                     12:  */
                     13: 
                     14: static int     smallbase = TRUE;       /* TRUE iff 2 <= output base <= 16 */
                     15: static int     logobase;               /* max number of chars per digit */
                     16: 
                     17: 
                     18: /*
                     19:  *     Putnum writes the rvalue pointed to by `a' onto the standard
                     20:  *     output.
                     21:  */
                     22: 
                     23: putnum(a)
                     24: rvalue *a;
                     25: {
                     26:        register int    scale;
                     27:        mint            intp,
                     28:                        fracp;
                     29:        register mint   *intpart = &intp,
                     30:                        *fracpart = &fracp;
                     31: 
                     32:        minit(intpart);
                     33:        minit(fracpart);
                     34:        scale = a->scale;
                     35:        mdiv(&a->mantissa, pow10(scale), intpart, fracpart);
                     36:        if (!ispos(&a->mantissa)) {
                     37:                mneg(intpart, intpart);
                     38:                mneg(fracpart, fracpart);
                     39:                pstring("-", 0);
                     40:        }
                     41:        if (!zerop(intpart) || scale == 0)
                     42:                if (smallbase)
                     43:                        smallint(intpart);
                     44:                else
                     45:                        bigint(intpart);
                     46:        mvfree(intpart);
                     47:        if (scale != 0)
                     48:                pfrac(fracpart, scale);
                     49:        mvfree(fracpart);
                     50: }
                     51: 
                     52: 
                     53: /*
                     54:  *     Smallint prints out the positive integer a in obase.
                     55:  */
                     56: 
                     57: static
                     58: smallint(a)
                     59: mint   *a;
                     60: {
                     61:        register char   *str;
                     62: 
                     63:        str = mtos(a);
                     64:        pstring(str, 0);
                     65:        mpfree(str);
                     66: }
                     67: 
                     68: 
                     69: /*
                     70:  *     Bigint prints out the positive integer a in outbase which
                     71:  *     is assumed to be "big".  It uses recursion to print the large
                     72:  *     "digits" in the correct order.
                     73:  *     Note that on exit, the value of `a' is grabage.
                     74:  */
                     75: 
                     76: static
                     77: bigint(a)
                     78: register mint  *a;
                     79: {
                     80:        mint    rm;
                     81:        register mint   *rem = &rm;
                     82:        register char   *str;
                     83: 
                     84:        minit(rem);
                     85:        mdiv(a, &outbase, a, rem);
                     86:        str = mtos(rem);
                     87:        mvfree(rem);
                     88:        if (zerop(a))
                     89:                pstring(str, 0);
                     90:        else {
                     91:                bigint(a);
                     92:                pstring(" ", 0);
                     93:                pstring(str, logobase);
                     94:        }
                     95:        mpfree(str);
                     96: }
                     97: 
                     98: 
                     99: /*
                    100:  *     Pfrac is used to print the fractional part when the output base
                    101:  *     is not 10.  `fracpart' is the fractional part times 10 to the
                    102:  *     `scale'.  Note that `fracpart' is destroyed.
                    103:  */
                    104: 
                    105: pfrac(fracpart, scale)
                    106: register mint  *fracpart;
                    107: int            scale;
                    108: {
                    109:        register int    digcnt;
                    110:        char            *str;
                    111:        mint            dig;
                    112: 
                    113:        pstring(".", 0);
                    114:        if (smallbase && obase == 10) {
                    115:                str = mtos(fracpart);
                    116:                pstring(str, scale);
                    117:                mpfree(str);
                    118:        } else {
                    119:                digcnt = (smallbase ? scale : (scale+logobase-1)/logobase);
                    120:                minit(&dig);
                    121:                do {
                    122:                        mult(fracpart, &outbase, fracpart);
                    123:                        mdiv(fracpart, pow10(scale), &dig, fracpart);
                    124:                        str = mtos(&dig);
                    125:                        pstring(str, logobase);
                    126:                        if (!smallbase)
                    127:                                pstring(" ", 0);
                    128:                        mpfree(str);
                    129:                } while (--digcnt > 0);
                    130:                mvfree(&dig);
                    131:        }
                    132: }
                    133: 
                    134: 
                    135: /*
                    136:  *     Sobase takes the rvalue pointed to by lval and sets the output
                    137:  *     base to it if it is an acceptable value.
                    138:  */
                    139: 
                    140: sobase(lval)
                    141: register rvalue        *lval;
                    142: {
                    143:        mint            tmp,
                    144:                        rem;
                    145:        register mint   *temp = &tmp;
                    146: 
                    147:        minit(temp);
                    148:        shift(&lval->mantissa, - lval->scale, temp);
                    149:        if (mcmp(mone, temp) >= 0)
                    150:                bcmerr("Invalid output base");
                    151:        mcopy(temp, &outbase);
                    152:        smallbase = mcmp(&outbase, &maxsobase) <= 0;
                    153:        if (smallbase)
                    154:                obase = mtoi(&outbase);
                    155:        else {
                    156:                obase = 10;
                    157:                msub(temp, mone, temp);
                    158:                minit(&rem);
                    159:                for (logobase = 0; !zerop(temp); ++logobase)
                    160:                        mdiv(temp, &ten, temp, &rem);
                    161:                mvfree(&rem);
                    162:        }
                    163:        mvfree(temp);
                    164: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.