|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.