|
|
1.1 root 1: /*
2: * Copyright (c) 1982 Regents of the University of California
3: */
4: #ifndef lint
5: static char sccsid[] = "@(#)bignum1.c 4.4 6/30/83";
6: #endif not lint
7:
8: #include <errno.h>
9: #include <stdio.h>
10: #include "as.h"
11:
12: Bignum Znumber;
13:
14: /*
15: * Construct an integer.
16: */
17:
18: Bignum as_atoi(ccp, radix, ovfp)
19: reg char *ccp; /* character cp */
20: int radix;
21: Ovf *ovfp;
22: {
23: reg chptr bcp;
24: chptr tcp;
25: reg int i;
26: int val;
27: Bignum n_n;
28: Bignum t_n;
29: int sign;
30: Ovf ovf;
31:
32: ovf = 0;
33: sign = 0;
34: for (; *ccp; ccp++){
35: switch(*ccp){
36: case '0':
37: case '+': continue;
38: case '-': sign ^= 1;
39: continue;
40: }
41: break;
42: }
43:
44: n_n = Znumber;
45: t_n = Znumber;
46: bcp = CH_FIELD(n_n); (void)numclear(bcp);
47: tcp = CH_FIELD(t_n); (void)numclear(tcp);
48: for (; *ccp; ccp++){
49: switch(*ccp){
50: case '8': case '9':
51: if (radix < 10)
52: goto done;
53: /*FALLTHROUGH*/
54: case '0': case '1': case '2': case '3': case '4':
55: case '5': case '6': case '7':
56: val = *ccp - '0';
57: break;
58: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
59: if (radix < 16)
60: goto done;
61: val = *ccp - 'A' + 10;
62: break;
63: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
64: if (radix < 16)
65: goto done;
66: val = *ccp - 'a' + 10;
67: break;
68: default:
69: goto done;
70: }
71: switch(radix){
72: case 8:
73: ovf |= numshift(3, bcp, bcp);
74: break;
75: case 16:
76: ovf |= numshift(4, bcp, bcp);
77: break;
78: case 10:
79: ovf |= numshift(1, tcp, bcp);
80: ovf |= numshift(3, bcp, bcp);
81: ovf |= numaddv(bcp, tcp, bcp);
82: break;
83: }
84: ovf |= numaddd(bcp, bcp, val);
85: }
86: done: ;
87: ovf |= posovf(bcp);
88: if (sign){
89: if (ovf & OVF_MAXINT) {
90: ovf &= ~(OVF_MAXINT | OVF_POSOVF);
91: } else {
92: ovf |= numnegate(bcp, bcp);
93: }
94: }
95: /*
96: * find the highest set unit of the number
97: */
98: val = sign ? -1 : 0;
99: for (i = 0; i < CH_N; i++){
100: if (bcp[i] == val)
101: break;
102: }
103: {
104: static u_char tagtab[4][8] = {
105: { TYPB,
106: TYPW,
107: TYPL, TYPL,
108: TYPQ, TYPQ, TYPQ, TYPQ },
109: { TYPW,
110: TYPL,
111: TYPQ, TYPQ },
112: { 0 },
113: { TYPL,
114: TYPQ }
115: };
116: /*
117: * i indexes to the null chunk; make it point to the
118: * last non null chunk
119: */
120: i -= 1;
121: if (i < 0)
122: i = 0;
123: n_n.num_tag = tagtab[HOC][i];
124: assert(n_n.num_tag != 0, " Botch width computation");
125: }
126: *ovfp = ovf;
127: return(n_n);
128: }
129:
130: Bignum as_atof (numbuf, radix)
131: char *numbuf;
132: {
133: double atof ();
134: Bignum number;
135:
136: number = Znumber;
137: number.num_tag = radix;
138: switch (radix)
139: {
140: case TYPD:
141: number.num_num.numFd_float.Fd_value = atof (numbuf);
142: break;
143: case TYPF:
144: number.num_num.numFf_float.Ff_value = atof (numbuf);
145: break;
146: }
147:
148: return (number);
149: }
150:
151: Ovf posovf(src)
152: reg chptr src;
153: {
154: reg int i;
155: Ovf overflow = 0;
156:
157: if (src[HOC] & SIGNBIT)
158: overflow = OVF_POSOVF;
159: if (src[HOC] == SIGNBIT){
160: for (i = HOC - 1; i >= 0; --i){
161: if (src[i] != 0)
162: return(overflow);
163: }
164: overflow |= OVF_MAXINT;
165: }
166: return(overflow);
167: }
168:
169: /*
170: * check if the number is clear
171: */
172: int isclear(dst)
173: reg chptr dst;
174: {
175: return(!isunequal(dst, CH_FIELD(Znumber)));
176: }
177:
178: int isunequal(src1, src2)
179: reg chptr src1, src2;
180: {
181: reg int i;
182:
183: i = CH_N;
184: do{
185: if (*src1++ != *src2++)
186: return(i);
187: }while(--i);
188: return(0);
189: }
190:
191: Ovf numclear(dst)
192: reg chptr dst;
193: {
194: reg int i;
195: i = CH_N;
196: do{
197: *dst++ = 0;
198: }while(--i);
199: return(0);
200: }
201:
202: Ovf numshift(n, dst, src)
203: int n;
204: reg chptr dst, src;
205: {
206: reg int i;
207: reg u_int carryi, carryo;
208: reg u_int mask;
209: reg u_int value;
210:
211: i = CH_N;
212: if (n == 0){
213: do{
214: *dst++ = *src++;
215: } while(--i);
216: return(0);
217: }
218:
219: carryi = 0;
220: mask = ONES(n);
221:
222: if (n > 0){
223: do{
224: value = *src++;
225: carryo = (value >> (CH_BITS - n)) & mask;
226: value <<= n;
227: value &= ~mask;
228: *dst++ = value | carryi;
229: carryi = carryo;
230: } while (--i);
231: return(carryi ? OVF_LSHIFT : 0);
232: } else {
233: n = -n;
234: src += CH_N;
235: dst += CH_N;
236: do{
237: value = *--src;
238: carryo = value & mask;
239: value >>= n;
240: value &= ONES(CH_BITS - n);
241: *--dst = value | carryi;
242: carryi = carryo << (CH_BITS - n);
243: } while (--i);
244: return(carryi ? OVF_LSHIFT : 0);
245: }
246: }
247:
248: Ovf numaddd(dst, src1, val)
249: chptr dst, src1;
250: int val;
251: {
252: static Bignum work;
253:
254: work.num_uchar[3] = val;
255: return (numaddv(dst, src1, CH_FIELD(work)));
256: }
257:
258: Ovf numaddv(dst, src1, src2)
259: reg chptr dst, src1, src2;
260: {
261: reg int i;
262: reg int carry;
263: reg u_int A,B,value;
264:
265: carry = 0;
266: i = CH_N;
267: do{
268: A = *src1++;
269: B = *src2++;
270: value = A + B + carry;
271: *dst++ = value;
272: carry = 0;
273: if (value < A || value < B)
274: carry = 1;
275: } while (--i);
276: return(carry ? OVF_ADDV : 0);
277: }
278:
279: Ovf numnegate(dst, src)
280: chptr dst, src;
281: {
282: Ovf ovf;
283:
284: ovf = num1comp(dst, src) ;
285: ovf |= numaddd(dst, dst, 1);
286: return(ovf);
287: }
288:
289: Ovf num1comp(dst, src)
290: reg chptr dst, src;
291: {
292: reg int i;
293: i = CH_N;
294: do{
295: *dst++ = ~ *src++;
296: }while (--i);
297: return(0);
298: }
299:
300: bignumprint(number)
301: Bignum number; /* number presented */
302: {
303: switch (num_type)
304: {
305: case TYPQ:
306: printf ("val[msd] = 0x%x, val[lsd] = 0x%x.",
307: number.num_num.numIq_int.Iq_ulong[1],
308: number.num_num.numIq_int.Iq_ulong[0]);
309: break;
310: case TYPF:
311: printf ("value %20.17f",
312: number.num_num.numFf_float.Ff_value);
313: break;
314: case TYPD:
315: printf ("value %20.17f",
316: number.num_num.numFd_float.Fd_value);
317: break;
318: default:
319: break;
320: }
321: }
322:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.