|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 3154 (0xc52) Types: TextFile Notes: UNIX file Names: »putnum.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/bc/putnum.c«
#include <stdio.h> #include "bc.h" /* * The current output base is encoded in several variables. * If every digit in the base can be represented by a single * char (ie. outbase <= maxsobase) then smallbase is TRUE and * obase contains the output base. If not then smallbase is * FALSE and obase contains 10. In any case, outbase contains * the current output base. */ static int smallbase = TRUE; /* TRUE iff 2 <= output base <= 16 */ static int logobase; /* max number of chars per digit */ /* * Putnum writes the rvalue pointed to by `a' onto the standard * output. */ putnum(a) rvalue *a; { register int scale; mint intp, fracp; register mint *intpart = &intp, *fracpart = &fracp; minit(intpart); minit(fracpart); scale = a->scale; mdiv(&a->mantissa, pow10(scale), intpart, fracpart); if (!ispos(&a->mantissa)) { mneg(intpart, intpart); mneg(fracpart, fracpart); pstring("-", 0); } if (!zerop(intpart) || scale == 0) if (smallbase) smallint(intpart); else bigint(intpart); mvfree(intpart); if (scale != 0) pfrac(fracpart, scale); mvfree(fracpart); } /* * Smallint prints out the positive integer a in obase. */ static smallint(a) mint *a; { register char *str; str = mtos(a); pstring(str, 0); mpfree(str); } /* * Bigint prints out the positive integer a in outbase which * is assumed to be "big". It uses recursion to print the large * "digits" in the correct order. * Note that on exit, the value of `a' is grabage. */ static bigint(a) register mint *a; { mint rm; register mint *rem = &rm; register char *str; minit(rem); mdiv(a, &outbase, a, rem); str = mtos(rem); mvfree(rem); if (zerop(a)) pstring(str, 0); else { bigint(a); pstring(" ", 0); pstring(str, logobase); } mpfree(str); } /* * Pfrac is used to print the fractional part when the output base * is not 10. `fracpart' is the fractional part times 10 to the * `scale'. Note that `fracpart' is destroyed. */ pfrac(fracpart, scale) register mint *fracpart; int scale; { register int digcnt; char *str; mint dig; pstring(".", 0); if (smallbase && obase == 10) { str = mtos(fracpart); pstring(str, scale); mpfree(str); } else { digcnt = (smallbase ? scale : (scale+logobase-1)/logobase); minit(&dig); do { mult(fracpart, &outbase, fracpart); mdiv(fracpart, pow10(scale), &dig, fracpart); str = mtos(&dig); pstring(str, logobase); if (!smallbase) pstring(" ", 0); mpfree(str); } while (--digcnt > 0); mvfree(&dig); } } /* * Sobase takes the rvalue pointed to by lval and sets the output * base to it if it is an acceptable value. */ sobase(lval) register rvalue *lval; { mint tmp, rem; register mint *temp = &tmp; minit(temp); shift(&lval->mantissa, - lval->scale, temp); if (mcmp(mone, temp) >= 0) bcmerr("Invalid output base"); mcopy(temp, &outbase); smallbase = mcmp(&outbase, &maxsobase) <= 0; if (smallbase) obase = mtoi(&outbase); else { obase = 10; msub(temp, mone, temp); minit(&rem); for (logobase = 0; !zerop(temp); ++logobase) mdiv(temp, &ten, temp, &rem); mvfree(&rem); } mvfree(temp); }