|
|
1.1 root 1: /*
2: * This file contains a (mostly) machine independent
3: * IEEE or DECVAX format floating point reader.
4: */
5:
6: #ifdef vax
7: #include "INC$LIB:cc0.h"
8: #else
9: #include "cc0.h"
10: #endif
11:
12: #if !NATIVEFP
13: #if IEEE|DECVAX
14:
15: #define NEGNUMB 01 /* # is negative */
16: #define DOTSEEN 02 /* A decimal point has appeared */
17: #define NEGDEXP 04 /* Decimal exp. is negative */
18:
19: /*
20: * The following values are returned on exponent overflow.
21: * The bits are the same in both formats.
22: * This does not use the special IEEE representation for Infinity.
23: */
24: static BIG poshuge = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
25: static BIG neghuge = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
26:
27: /*
28: * Transform a number from ASCII to either
29: * IEEE format double precision or
30: * DEC VAX-11 format double precision.
31: * Stash the result in the supplied character array.
32: * The 0'th element gets the exponent end of the number.
33: * The internal representation used here is a BIG,
34: * an array of bytes containing the binary mantissa.
35: */
36: dvalread(dvalp, sp)
37: char *dvalp;
38: register char *sp;
39: {
40: register int c;
41: int binexp, decexp;
42: int flags, i, n;
43: BIG num, tmp;
44:
45: intclr(num);
46: flags = 0;
47: decexp = 0;
48: binexp = 64;
49: if (*sp == '+')
50: ++sp;
51: else if (*sp == '-') {
52: flags |= NEGNUMB;
53: ++sp;
54: }
55: while ((c = *sp++)=='.' || (c>='0' && c<='9')) {
56: if (c == '.') {
57: if ((flags&DOTSEEN) != 0)
58: break;
59: flags |= DOTSEEN;
60: } else {
61: if (t5ne(num))
62: ++decexp;
63: else {
64: intshl(num);
65: intcpy(tmp, num);
66: intshl(num);
67: intshl(num);
68: intadd(num, tmp);
69: intclr(tmp);
70: tmp[NBIG-1] = c-'0';
71: intadd(num, tmp);
72: }
73: if ((flags&DOTSEEN) != 0)
74: --decexp;
75: }
76: }
77: /*
78: * If the delimiter is an 'e' or an 'E',
79: * read in the exponent and adjust the decimal bias.
80: */
81: if (c=='e' || c=='E') {
82: if (*sp == '+')
83: ++sp;
84: else if (*sp == '-') {
85: flags |= NEGDEXP;
86: ++sp;
87: }
88: n = 0;
89: while ((c = *sp++)>='0' && c<='9')
90: n = 10*n + c - '0';
91: if ((flags&NEGDEXP) != 0)
92: n = -n;
93: decexp += n;
94: }
95: /*
96: * Check for 0.0.
97: * Double 0.0 is a BIG containing all 0 bytes in both formats.
98: */
99: for (i=0; i<NBIG && num[i]==0; ++i)
100: ;
101: if (i == NBIG) {
102: intclr(dvalp);
103: return;
104: }
105: /*
106: * Multiply.
107: * Try to do a *5.
108: * If ok, add 1 to the binary exponent (2*5=10).
109: * Otherwise, multiply by 5/4, add 3 to the binary exponent (5/4*8=10).
110: */
111: if (decexp > 0) {
112: do {
113: intcpy(tmp, num);
114: if (intshl(tmp)==0 && intshl(tmp)==0
115: && intadd(tmp, num)==0) {
116: intcpy(num, tmp);
117: ++binexp;
118: } else {
119: intcpy(tmp, num);
120: intshr(tmp);
121: intshr(tmp);
122: if (intadd(num, tmp) != 0) {
123: ++binexp;
124: intshr(num);
125: num[0] |= MSBBIG;
126: }
127: binexp += 3;
128: }
129: } while (--decexp);
130: /*
131: * Divide.
132: * At each iteration, subtract 3 from the exponent
133: * and multiply by 4/5 (4/5*1/8=1/10).
134: * 4/5 = 0.1100110011001100....
135: */
136: } else if (decexp < 0) {
137: do {
138: while ((num[0]&MSBBIG) == 0) {
139: intshl(num);
140: --binexp;
141: }
142: intshr(num);
143: intcpy(tmp, num);
144: for (i=0; i<32; ++i) {
145: if ((i&01) != 0) {
146: intshr(tmp);
147: intshr(tmp);
148: }
149: intshr(tmp);
150: intadd(num, tmp);
151: }
152: binexp -= 3;
153: } while (++decexp);
154: }
155: /*
156: * Normalize and eat up the hidden bit.
157: */
158: do {
159: --binexp;
160: } while (intshl(num) == 0);
161: intclr(tmp);
162: tmp[IROUND] = BROUND;
163: if (intadd(num, tmp) != 0) {
164: ++binexp;
165: intshr(num);
166: }
167: /*
168: * Bias the exponent and check its range.
169: * This does not bother to use the special IEEE representation
170: * (exponent 0, mantissa nonzero) for a bit more range.
171: * Overflow returns the biggest value in the normal representation;
172: * IEEE overflow could return Infinity instead but currently does not.
173: */
174: binexp += EXPBIAS;
175: if (binexp <= 0) {
176: cwarn("exponent underflow in floating point constant");
177: intclr(dvalp);
178: return;
179: }
180: if (binexp > EXPMAX) {
181: cwarn("exponent overflow in floating point constant");
182: intcpy(dvalp, (flags&NEGNUMB)!=0 ? neghuge : poshuge);
183: return;
184: }
185: /*
186: * Pack up and return home.
187: */
188: #if IEEE
189: for (i=0; i<12; ++i)
190: intshr(num);
191: num[0] = (binexp>>4) & 0177;
192: num[1] |= (binexp<<4) & 0360;
193: #else
194: for (i=0; i<9; ++i)
195: intshr(num);
196: num[0] = (binexp>>1) & 0177;
197: num[1] |= (binexp<<7) & 0200;
198: #endif
199: if (flags&NEGNUMB != 0)
200: num[0] |= MSBBIG;
201: intcpy(dvalp, num);
202: }
203:
204: /*
205: * Shift a BIG right by 1 bit.
206: * Shift a 0 into the leftmost position.
207: * Return the bit that gets shot off the end.
208: */
209: intshr(num)
210: BIG num;
211: {
212: register int i, ocarry, icarry;
213:
214: ocarry = 0;
215: for (i=0; i<NBIG; ++i) {
216: icarry = ocarry;
217: ocarry = num[i]&01;
218: num[i] >>= 1;
219: if (icarry != 0)
220: num[i] |= MSBBIG;
221: }
222: return (ocarry);
223: }
224:
225: /*
226: * Shift a BIG left by 1 bit.
227: * Shift a 0 into the rightmost position.
228: * Return the bit that gets shot off the end.
229: */
230: static
231: intshl(num)
232: BIG num;
233: {
234: register int i, ocarry, icarry;
235:
236: ocarry = 0;
237: for (i=NBIG-1; i>=0; --i) {
238: icarry = ocarry;
239: ocarry = num[i]&MSBBIG;
240: num[i] <<= 1;
241: if (icarry != 0)
242: num[i] |= 1;
243: }
244: return (ocarry);
245: }
246:
247: /*
248: * Add two BIGs.
249: * Return the carry bit.
250: */
251: intadd(num, tmp)
252: BIG num;
253: BIG tmp;
254: {
255: register int i, sum;
256:
257: sum = 0;
258: for (i=NBIG-1; i>=0; --i) {
259: sum += num[i] + tmp[i];
260: num[i] = sum;
261: sum = cbit(sum);
262: }
263: return (sum);
264: }
265:
266: /*
267: * Copy a BIG.
268: */
269: intcpy(tint, fint)
270: BIG tint;
271: BIG fint;
272: {
273: register int i;
274:
275: for (i=0; i<NBIG; ++i)
276: tint[i] = fint[i];
277: }
278:
279: /*
280: * Set a BIG to 0.
281: */
282: intclr(tint)
283: BIG tint;
284: {
285: register int i;
286:
287: for (i=0; i<NBIG; ++i)
288: tint[i] = 0;
289: }
290:
291: #endif
292: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.