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;