2 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 See the copyright notice in the ACK home directory, in the file "Copyright".
19 This is a routine to do the work.
20 There are two versions:
21 One is based on the partial products method
22 and makes no use possible machine instructions
23 to divide (hardware dividers).
24 The other is used when USE_DIVIDE is defined. It is much faster on
25 machines with fast 4 byte operations.
27 /********************************************************/
35 register unsigned long *lp;
39 unsigned short u[9], v[5];
41 register unsigned short *u_p = u;
45 if ((e2->m1 | e2->m2) == 0) {
47 * Exception 8.2 - Divide by zero
54 if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */
55 e1->exp = 0; /* make sure */
60 * numbers are right shifted one bit to make sure
61 * that m1 is quaranteed to be larger if its
64 b64_rsft(&e1->mantissa); /* 64 bit shift right */
65 b64_rsft(&e2->mantissa); /* 64 bit shift right */
69 /* check for underflow, divide by zero, etc */
74 /* do division of mantissas */
75 /* uses partial product method */
76 /* init control variables */
82 /* partial product division loop */
85 /* first left shift result 1 bit */
86 /* this is ALWAYS done */
90 /* compare dividend and divisor */
91 /* if dividend >= divisor add a bit */
92 /* and subtract divisior from dividend */
94 if ( (e1->m1 < e2->m1) ||
95 ((e1->m1 == e2->m1) && (e1->m2 < e2->m2) ))
96 ; /* null statement */
97 /* i.e., don't add or subtract */
99 result.l_32++; /* ADD */
101 e1->m1 -= 1; /* carry in */
102 e1->m1 -= e2->m1; /* do SUBTRACTION */
103 e1->m2 -= e2->m2; /* SUBTRACTION */
106 /* shift dividend left one bit OR */
107 /* IF it equals ZERO we can break out */
108 /* of the loop, but still must shift */
109 /* the quotient the remaining count bits */
110 /* NB save the results of this test in error */
111 /* if not zero, then the result is inexact. */
112 /* this would be reported in IEEE standard */
114 /* lp points to dividend */
117 error = ((*lp | *(lp+1)) != 0L) ? 1 : 0;
118 if (error) { /* more work */
119 /* assume max bit == 0 (see above) */
120 b64_lsft(&e1->mantissa);
124 break; /* leave loop */
125 } /* end of divide by subtraction loop */
129 if (count > 31) { /* move to higher word */
132 *(lp+1) = 0L; /* clear low word */
135 *lp <<= count; /* shift rest of way */
136 lp++; /* == &result.l_32 */
138 result.h_32 |= (*lp >> 32-count);
142 #else /* USE_DIVIDE */
144 u[4] = (e1->m2 & 1) << 15;
145 b64_rsft(&(e1->mantissa));
150 u[5] = 0; u[6] = 0; u[7] = 0;
155 while (! v[maxv]) maxv--;
161 * Use an algorithm of Knuth (The art of programming, Seminumerical
162 * algorithms), to divide u by v. u and v are both seen as numbers
165 for (j = 0; j <= 3; j++, u_p++) {
166 unsigned long q_est, temp;
169 if (u_p[0] == 0 && u_p[1] < v[1]) continue;
170 temp = ((unsigned long)u_p[0] << 16) + u_p[1];
171 if (u_p[0] >= v[1]) {
177 temp -= q_est * v[1];
178 while (temp < 0x10000 && v[2]*q_est > ((temp<<16)+u_p[2])) {
182 /* Now, according to Knuth, we have an estimate of the
183 quotient, that is either correct or one too big, but
184 almost always correct.
191 for (i = maxv; i > 0; i--) {
192 unsigned long tmp = q_est * v[i] + k + borrow;
193 unsigned short md = tmp;
195 borrow = (md > u_p[i]);
204 /* So, this does not happen often; the estimate
205 was one too big; correct this
207 *lp |= (j & 1) ? (q_est - 1) : ((q_est-1)<<16);
209 for (i = maxv; i > 0; i--) {
211 = v[i]+(unsigned long)u_p[i]+borrow;
218 else *lp |= (j & 1) ? q_est : (q_est<<16);
221 #ifdef EXCEPTION_INEXACT
223 for (j = 7; j >= 0; j--) {
232 #ifdef EXCEPTION_INEXACT
235 * report here exception 8.5 - Inexact
236 * from Draft 8.0 of IEEE P754:
237 * In the absence of an invalid operation exception,
238 * if the rounded result of an operation is not exact or if
239 * it overflows without a trap, then the inexact exception
240 * shall be assigned. The rounded or overflowed result
241 * shall be delivered to the destination.
245 e1->mantissa = result;
248 if (e1->exp < EXT_MIN) {
250 * Exception 8.4 - Underflow
252 trap(EFUNFL); /* underflow */
254 e1->m1 = e1->m2 = 0L;
257 if (e1->exp >= EXT_MAX) {
259 * Exception 8.3 - Overflow
261 trap(EFOVFL); /* overflow */
263 e1->m1 = e1->m2 = 0L;