Annotation of coherent/d/bin/bc/putnum.c, revision 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.