Mercurial > hg > CbC > CbC_gcc
comparison libgcc/config/libbid/bid64_compare.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Copyright (C) 2007, 2009 Free Software Foundation, Inc. | |
2 | |
3 This file is part of GCC. | |
4 | |
5 GCC is free software; you can redistribute it and/or modify it under | |
6 the terms of the GNU General Public License as published by the Free | |
7 Software Foundation; either version 3, or (at your option) any later | |
8 version. | |
9 | |
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 for more details. | |
14 | |
15 Under Section 7 of GPL version 3, you are granted additional | |
16 permissions described in the GCC Runtime Library Exception, version | |
17 3.1, as published by the Free Software Foundation. | |
18 | |
19 You should have received a copy of the GNU General Public License and | |
20 a copy of the GCC Runtime Library Exception along with this program; | |
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
22 <http://www.gnu.org/licenses/>. */ | |
23 | |
24 #include "bid_internal.h" | |
25 | |
26 static const UINT64 mult_factor[16] = { | |
27 1ull, 10ull, 100ull, 1000ull, | |
28 10000ull, 100000ull, 1000000ull, 10000000ull, | |
29 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull, | |
30 1000000000000ull, 10000000000000ull, | |
31 100000000000000ull, 1000000000000000ull | |
32 }; | |
33 | |
34 #if DECIMAL_CALL_BY_REFERENCE | |
35 void | |
36 bid64_quiet_equal (int *pres, UINT64 * px, | |
37 UINT64 * | |
38 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
39 _EXC_INFO_PARAM) { | |
40 UINT64 x = *px; | |
41 UINT64 y = *py; | |
42 #else | |
43 int | |
44 bid64_quiet_equal (UINT64 x, | |
45 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
46 _EXC_INFO_PARAM) { | |
47 #endif | |
48 int res; | |
49 int exp_x, exp_y, exp_t; | |
50 UINT64 sig_x, sig_y, sig_t; | |
51 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y, lcv; | |
52 | |
53 // NaN (CASE1) | |
54 // if either number is NAN, the comparison is unordered, | |
55 // rather than equal : return 0 | |
56 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
57 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
58 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
59 } | |
60 res = 0; | |
61 BID_RETURN (res); | |
62 } | |
63 // SIMPLE (CASE2) | |
64 // if all the bits are the same, these numbers are equivalent. | |
65 if (x == y) { | |
66 res = 1; | |
67 BID_RETURN (res); | |
68 } | |
69 // INFINITY (CASE3) | |
70 if (((x & MASK_INF) == MASK_INF) && ((y & MASK_INF) == MASK_INF)) { | |
71 res = (((x ^ y) & MASK_SIGN) != MASK_SIGN); | |
72 BID_RETURN (res); | |
73 } | |
74 // ONE INFINITY (CASE3') | |
75 if (((x & MASK_INF) == MASK_INF) || ((y & MASK_INF) == MASK_INF)) { | |
76 res = 0; | |
77 BID_RETURN (res); | |
78 } | |
79 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
80 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
81 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
82 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
83 if (sig_x > 9999999999999999ull) { | |
84 non_canon_x = 1; | |
85 } else { | |
86 non_canon_x = 0; | |
87 } | |
88 } else { | |
89 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
90 sig_x = (x & MASK_BINARY_SIG1); | |
91 non_canon_x = 0; | |
92 } | |
93 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
94 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
95 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
96 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
97 if (sig_y > 9999999999999999ull) { | |
98 non_canon_y = 1; | |
99 } else { | |
100 non_canon_y = 0; | |
101 } | |
102 } else { | |
103 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
104 sig_y = (y & MASK_BINARY_SIG1); | |
105 non_canon_y = 0; | |
106 } | |
107 // ZERO (CASE4) | |
108 // some properties: | |
109 // (+ZERO==-ZERO) => therefore ignore the sign | |
110 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
111 // therefore ignore the exponent field | |
112 // (Any non-canonical # is considered 0) | |
113 if (non_canon_x || sig_x == 0) { | |
114 x_is_zero = 1; | |
115 } | |
116 if (non_canon_y || sig_y == 0) { | |
117 y_is_zero = 1; | |
118 } | |
119 if (x_is_zero && y_is_zero) { | |
120 res = 1; | |
121 BID_RETURN (res); | |
122 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) { | |
123 res = 0; | |
124 BID_RETURN (res); | |
125 } | |
126 // OPPOSITE SIGN (CASE5) | |
127 // now, if the sign bits differ => not equal : return 0 | |
128 if ((x ^ y) & MASK_SIGN) { | |
129 res = 0; | |
130 BID_RETURN (res); | |
131 } | |
132 // REDUNDANT REPRESENTATIONS (CASE6) | |
133 if (exp_x > exp_y) { // to simplify the loop below, | |
134 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y, | |
135 SWAP (sig_x, sig_y, sig_t); // and the smaller exp in x | |
136 } | |
137 if (exp_y - exp_x > 15) { | |
138 res = 0; // difference cannot be greater than 10^15 | |
139 BID_RETURN (res); | |
140 } | |
141 for (lcv = 0; lcv < (exp_y - exp_x); lcv++) { | |
142 // recalculate y's significand upwards | |
143 sig_y = sig_y * 10; | |
144 if (sig_y > 9999999999999999ull) { | |
145 res = 0; | |
146 BID_RETURN (res); | |
147 } | |
148 } | |
149 res = (sig_y == sig_x); | |
150 BID_RETURN (res); | |
151 } | |
152 | |
153 #if DECIMAL_CALL_BY_REFERENCE | |
154 void | |
155 bid64_quiet_greater (int *pres, UINT64 * px, | |
156 UINT64 * | |
157 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
158 _EXC_INFO_PARAM) { | |
159 UINT64 x = *px; | |
160 UINT64 y = *py; | |
161 #else | |
162 int | |
163 bid64_quiet_greater (UINT64 x, | |
164 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
165 _EXC_INFO_PARAM) { | |
166 #endif | |
167 int res; | |
168 int exp_x, exp_y; | |
169 UINT64 sig_x, sig_y; | |
170 UINT128 sig_n_prime; | |
171 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
172 | |
173 // NaN (CASE1) | |
174 // if either number is NAN, the comparison is unordered, rather than equal : | |
175 // return 0 | |
176 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
177 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
178 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
179 } | |
180 res = 0; | |
181 BID_RETURN (res); | |
182 } | |
183 // SIMPLE (CASE2) | |
184 // if all the bits are the same, these numbers are equal (not Greater). | |
185 if (x == y) { | |
186 res = 0; | |
187 BID_RETURN (res); | |
188 } | |
189 // INFINITY (CASE3) | |
190 if ((x & MASK_INF) == MASK_INF) { | |
191 // if x is neg infinity, there is no way it is greater than y, return 0 | |
192 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
193 res = 0; | |
194 BID_RETURN (res); | |
195 } else { | |
196 // x is pos infinity, it is greater, unless y is positive | |
197 // infinity => return y!=pos_infinity | |
198 res = (((y & MASK_INF) != MASK_INF) | |
199 || ((y & MASK_SIGN) == MASK_SIGN)); | |
200 BID_RETURN (res); | |
201 } | |
202 } else if ((y & MASK_INF) == MASK_INF) { | |
203 // x is finite, so if y is positive infinity, then x is less, return 0 | |
204 // if y is negative infinity, then x is greater, return 1 | |
205 res = ((y & MASK_SIGN) == MASK_SIGN); | |
206 BID_RETURN (res); | |
207 } | |
208 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
209 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
210 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
211 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
212 if (sig_x > 9999999999999999ull) { | |
213 non_canon_x = 1; | |
214 } else { | |
215 non_canon_x = 0; | |
216 } | |
217 } else { | |
218 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
219 sig_x = (x & MASK_BINARY_SIG1); | |
220 non_canon_x = 0; | |
221 } | |
222 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
223 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
224 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
225 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
226 if (sig_y > 9999999999999999ull) { | |
227 non_canon_y = 1; | |
228 } else { | |
229 non_canon_y = 0; | |
230 } | |
231 } else { | |
232 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
233 sig_y = (y & MASK_BINARY_SIG1); | |
234 non_canon_y = 0; | |
235 } | |
236 // ZERO (CASE4) | |
237 // some properties: | |
238 //(+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
239 //(ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore ignore the | |
240 // exponent field | |
241 // (Any non-canonical # is considered 0) | |
242 if (non_canon_x || sig_x == 0) { | |
243 x_is_zero = 1; | |
244 } | |
245 if (non_canon_y || sig_y == 0) { | |
246 y_is_zero = 1; | |
247 } | |
248 // if both numbers are zero, neither is greater => return NOTGREATERTHAN | |
249 if (x_is_zero && y_is_zero) { | |
250 res = 0; | |
251 BID_RETURN (res); | |
252 } else if (x_is_zero) { | |
253 // is x is zero, it is greater if Y is negative | |
254 res = ((y & MASK_SIGN) == MASK_SIGN); | |
255 BID_RETURN (res); | |
256 } else if (y_is_zero) { | |
257 // is y is zero, X is greater if it is positive | |
258 res = ((x & MASK_SIGN) != MASK_SIGN); | |
259 BID_RETURN (res); | |
260 } | |
261 // OPPOSITE SIGN (CASE5) | |
262 // now, if the sign bits differ, x is greater if y is negative | |
263 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
264 res = ((y & MASK_SIGN) == MASK_SIGN); | |
265 BID_RETURN (res); | |
266 } | |
267 // REDUNDANT REPRESENTATIONS (CASE6) | |
268 // if both components are either bigger or smaller, | |
269 // it is clear what needs to be done | |
270 if (sig_x > sig_y && exp_x > exp_y) { | |
271 res = ((x & MASK_SIGN) != MASK_SIGN); | |
272 BID_RETURN (res); | |
273 } | |
274 if (sig_x < sig_y && exp_x < exp_y) { | |
275 res = ((x & MASK_SIGN) == MASK_SIGN); | |
276 BID_RETURN (res); | |
277 } | |
278 // if exp_x is 15 greater than exp_y, no need for compensation | |
279 if (exp_x - exp_y > 15) { // difference cannot be greater than 10^15 | |
280 if (x & MASK_SIGN) // if both are negative | |
281 res = 0; | |
282 else // if both are positive | |
283 res = 1; | |
284 BID_RETURN (res); | |
285 } | |
286 // if exp_x is 15 less than exp_y, no need for compensation | |
287 if (exp_y - exp_x > 15) { | |
288 if (x & MASK_SIGN) // if both are negative | |
289 res = 1; | |
290 else // if both are positive | |
291 res = 0; | |
292 BID_RETURN (res); | |
293 } | |
294 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
295 if (exp_x > exp_y) { // to simplify the loop below, | |
296 // otherwise adjust the x significand upwards | |
297 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
298 mult_factor[exp_x - exp_y]); | |
299 // if postitive, return whichever significand is larger (converse if neg.) | |
300 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
301 res = 0; | |
302 BID_RETURN (res); | |
303 } | |
304 res = (((sig_n_prime.w[1] > 0) | |
305 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) == | |
306 MASK_SIGN)); | |
307 BID_RETURN (res); | |
308 } | |
309 // adjust the y significand upwards | |
310 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
311 mult_factor[exp_y - exp_x]); | |
312 // if postitive, return whichever significand is larger | |
313 // (converse if negative) | |
314 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
315 res = 0; | |
316 BID_RETURN (res); | |
317 } | |
318 res = (((sig_n_prime.w[1] == 0) | |
319 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
320 MASK_SIGN)); | |
321 BID_RETURN (res); | |
322 } | |
323 | |
324 #if DECIMAL_CALL_BY_REFERENCE | |
325 void | |
326 bid64_quiet_greater_equal (int *pres, UINT64 * px, | |
327 UINT64 * | |
328 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
329 _EXC_INFO_PARAM) { | |
330 UINT64 x = *px; | |
331 UINT64 y = *py; | |
332 #else | |
333 int | |
334 bid64_quiet_greater_equal (UINT64 x, | |
335 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
336 _EXC_INFO_PARAM) { | |
337 #endif | |
338 int res; | |
339 int exp_x, exp_y; | |
340 UINT64 sig_x, sig_y; | |
341 UINT128 sig_n_prime; | |
342 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
343 | |
344 // NaN (CASE1) | |
345 // if either number is NAN, the comparison is unordered : return 1 | |
346 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
347 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
348 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
349 } | |
350 res = 0; | |
351 BID_RETURN (res); | |
352 } | |
353 // SIMPLE (CASE2) | |
354 // if all the bits are the same, these numbers are equal. | |
355 if (x == y) { | |
356 res = 1; | |
357 BID_RETURN (res); | |
358 } | |
359 // INFINITY (CASE3) | |
360 if ((x & MASK_INF) == MASK_INF) { | |
361 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } | |
362 if ((x & MASK_SIGN) == MASK_SIGN) { | |
363 // x is -inf, so it is less than y unless y is -inf | |
364 res = (((y & MASK_INF) == MASK_INF) | |
365 && (y & MASK_SIGN) == MASK_SIGN); | |
366 BID_RETURN (res); | |
367 } else { // x is pos_inf, no way for it to be less than y | |
368 res = 1; | |
369 BID_RETURN (res); | |
370 } | |
371 } else if ((y & MASK_INF) == MASK_INF) { | |
372 // x is finite, so: | |
373 // if y is +inf, x<y | |
374 // if y is -inf, x>y | |
375 res = ((y & MASK_SIGN) == MASK_SIGN); | |
376 BID_RETURN (res); | |
377 } | |
378 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
379 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
380 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
381 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
382 if (sig_x > 9999999999999999ull) { | |
383 non_canon_x = 1; | |
384 } else { | |
385 non_canon_x = 0; | |
386 } | |
387 } else { | |
388 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
389 sig_x = (x & MASK_BINARY_SIG1); | |
390 non_canon_x = 0; | |
391 } | |
392 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
393 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
394 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
395 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
396 if (sig_y > 9999999999999999ull) { | |
397 non_canon_y = 1; | |
398 } else { | |
399 non_canon_y = 0; | |
400 } | |
401 } else { | |
402 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
403 sig_y = (y & MASK_BINARY_SIG1); | |
404 non_canon_y = 0; | |
405 } | |
406 // ZERO (CASE4) | |
407 // some properties: | |
408 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
409 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
410 // therefore ignore the exponent field | |
411 // (Any non-canonical # is considered 0) | |
412 if (non_canon_x || sig_x == 0) { | |
413 x_is_zero = 1; | |
414 } | |
415 if (non_canon_y || sig_y == 0) { | |
416 y_is_zero = 1; | |
417 } | |
418 if (x_is_zero && y_is_zero) { | |
419 // if both numbers are zero, they are equal | |
420 res = 1; | |
421 BID_RETURN (res); | |
422 } else if (x_is_zero) { | |
423 // if x is zero, it is lessthan if Y is positive | |
424 res = ((y & MASK_SIGN) == MASK_SIGN); | |
425 BID_RETURN (res); | |
426 } else if (y_is_zero) { | |
427 // if y is zero, X is less if it is negative | |
428 res = ((x & MASK_SIGN) != MASK_SIGN); | |
429 BID_RETURN (res); | |
430 } | |
431 // OPPOSITE SIGN (CASE5) | |
432 // now, if the sign bits differ, x is less than if y is positive | |
433 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
434 res = ((y & MASK_SIGN) == MASK_SIGN); | |
435 BID_RETURN (res); | |
436 } | |
437 // REDUNDANT REPRESENTATIONS (CASE6) | |
438 // if both components are either bigger or smaller | |
439 if (sig_x > sig_y && exp_x >= exp_y) { | |
440 res = ((x & MASK_SIGN) != MASK_SIGN); | |
441 BID_RETURN (res); | |
442 } | |
443 if (sig_x < sig_y && exp_x <= exp_y) { | |
444 res = ((x & MASK_SIGN) == MASK_SIGN); | |
445 BID_RETURN (res); | |
446 } | |
447 // if exp_x is 15 greater than exp_y, no need for compensation | |
448 if (exp_x - exp_y > 15) { | |
449 res = ((x & MASK_SIGN) != MASK_SIGN); | |
450 // difference cannot be greater than 10^15 | |
451 BID_RETURN (res); | |
452 } | |
453 // if exp_x is 15 less than exp_y, no need for compensation | |
454 if (exp_y - exp_x > 15) { | |
455 res = ((x & MASK_SIGN) == MASK_SIGN); | |
456 BID_RETURN (res); | |
457 } | |
458 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
459 if (exp_x > exp_y) { // to simplify the loop below, | |
460 // otherwise adjust the x significand upwards | |
461 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
462 mult_factor[exp_x - exp_y]); | |
463 // return 1 if values are equal | |
464 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
465 res = 1; | |
466 BID_RETURN (res); | |
467 } | |
468 // if postitive, return whichever significand abs is smaller | |
469 // (converse if negative) | |
470 res = (((sig_n_prime.w[1] == 0) | |
471 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) != | |
472 MASK_SIGN)); | |
473 BID_RETURN (res); | |
474 } | |
475 // adjust the y significand upwards | |
476 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
477 mult_factor[exp_y - exp_x]); | |
478 // return 0 if values are equal | |
479 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
480 res = 1; | |
481 BID_RETURN (res); | |
482 } | |
483 // if positive, return whichever significand abs is smaller | |
484 // (converse if negative) | |
485 res = (((sig_n_prime.w[1] > 0) | |
486 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) != | |
487 MASK_SIGN)); | |
488 BID_RETURN (res); | |
489 } | |
490 | |
491 #if DECIMAL_CALL_BY_REFERENCE | |
492 void | |
493 bid64_quiet_greater_unordered (int *pres, UINT64 * px, | |
494 UINT64 * | |
495 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
496 _EXC_INFO_PARAM) { | |
497 UINT64 x = *px; | |
498 UINT64 y = *py; | |
499 #else | |
500 int | |
501 bid64_quiet_greater_unordered (UINT64 x, | |
502 UINT64 y _EXC_FLAGS_PARAM | |
503 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { | |
504 #endif | |
505 int res; | |
506 int exp_x, exp_y; | |
507 UINT64 sig_x, sig_y; | |
508 UINT128 sig_n_prime; | |
509 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
510 | |
511 // NaN (CASE1) | |
512 // if either number is NAN, the comparison is unordered, rather than equal : | |
513 // return 0 | |
514 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
515 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
516 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
517 } | |
518 res = 1; | |
519 BID_RETURN (res); | |
520 } | |
521 // SIMPLE (CASE2) | |
522 // if all the bits are the same, these numbers are equal (not Greater). | |
523 if (x == y) { | |
524 res = 0; | |
525 BID_RETURN (res); | |
526 } | |
527 // INFINITY (CASE3) | |
528 if ((x & MASK_INF) == MASK_INF) { | |
529 // if x is neg infinity, there is no way it is greater than y, return 0 | |
530 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
531 res = 0; | |
532 BID_RETURN (res); | |
533 } else { | |
534 // x is pos infinity, it is greater, unless y is positive infinity => | |
535 // return y!=pos_infinity | |
536 res = (((y & MASK_INF) != MASK_INF) | |
537 || ((y & MASK_SIGN) == MASK_SIGN)); | |
538 BID_RETURN (res); | |
539 } | |
540 } else if ((y & MASK_INF) == MASK_INF) { | |
541 // x is finite, so if y is positive infinity, then x is less, return 0 | |
542 // if y is negative infinity, then x is greater, return 1 | |
543 res = ((y & MASK_SIGN) == MASK_SIGN); | |
544 BID_RETURN (res); | |
545 } | |
546 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
547 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
548 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
549 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
550 if (sig_x > 9999999999999999ull) { | |
551 non_canon_x = 1; | |
552 } else { | |
553 non_canon_x = 0; | |
554 } | |
555 } else { | |
556 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
557 sig_x = (x & MASK_BINARY_SIG1); | |
558 non_canon_x = 0; | |
559 } | |
560 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
561 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
562 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
563 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
564 if (sig_y > 9999999999999999ull) { | |
565 non_canon_y = 1; | |
566 } else { | |
567 non_canon_y = 0; | |
568 } | |
569 } else { | |
570 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
571 sig_y = (y & MASK_BINARY_SIG1); | |
572 non_canon_y = 0; | |
573 } | |
574 // ZERO (CASE4) | |
575 // some properties: | |
576 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
577 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
578 // therefore ignore the exponent field | |
579 // (Any non-canonical # is considered 0) | |
580 if (non_canon_x || sig_x == 0) { | |
581 x_is_zero = 1; | |
582 } | |
583 if (non_canon_y || sig_y == 0) { | |
584 y_is_zero = 1; | |
585 } | |
586 // if both numbers are zero, neither is greater => return NOTGREATERTHAN | |
587 if (x_is_zero && y_is_zero) { | |
588 res = 0; | |
589 BID_RETURN (res); | |
590 } else if (x_is_zero) { | |
591 // is x is zero, it is greater if Y is negative | |
592 res = ((y & MASK_SIGN) == MASK_SIGN); | |
593 BID_RETURN (res); | |
594 } else if (y_is_zero) { | |
595 // is y is zero, X is greater if it is positive | |
596 res = ((x & MASK_SIGN) != MASK_SIGN); | |
597 BID_RETURN (res); | |
598 } | |
599 // OPPOSITE SIGN (CASE5) | |
600 // now, if the sign bits differ, x is greater if y is negative | |
601 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
602 res = ((y & MASK_SIGN) == MASK_SIGN); | |
603 BID_RETURN (res); | |
604 } | |
605 // REDUNDANT REPRESENTATIONS (CASE6) | |
606 // if both components are either bigger or smaller | |
607 if (sig_x > sig_y && exp_x >= exp_y) { | |
608 res = ((x & MASK_SIGN) != MASK_SIGN); | |
609 BID_RETURN (res); | |
610 } | |
611 if (sig_x < sig_y && exp_x <= exp_y) { | |
612 res = ((x & MASK_SIGN) == MASK_SIGN); | |
613 BID_RETURN (res); | |
614 } | |
615 // if exp_x is 15 greater than exp_y, no need for compensation | |
616 if (exp_x - exp_y > 15) { | |
617 // difference cannot be greater than 10^15 | |
618 res = ((x & MASK_SIGN) != MASK_SIGN); | |
619 BID_RETURN (res); | |
620 } | |
621 // if exp_x is 15 less than exp_y, no need for compensation | |
622 if (exp_y - exp_x > 15) { | |
623 res = ((x & MASK_SIGN) == MASK_SIGN); | |
624 BID_RETURN (res); | |
625 } | |
626 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
627 if (exp_x > exp_y) { // to simplify the loop below, | |
628 // otherwise adjust the x significand upwards | |
629 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
630 mult_factor[exp_x - exp_y]); | |
631 // if postitive, return whichever significand is larger | |
632 // (converse if negative) | |
633 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
634 res = 0; | |
635 BID_RETURN (res); | |
636 } | |
637 res = (((sig_n_prime.w[1] > 0) | |
638 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) == | |
639 MASK_SIGN)); | |
640 BID_RETURN (res); | |
641 } | |
642 // adjust the y significand upwards | |
643 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
644 mult_factor[exp_y - exp_x]); | |
645 // if postitive, return whichever significand is larger (converse if negative) | |
646 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
647 res = 0; | |
648 BID_RETURN (res); | |
649 } | |
650 res = (((sig_n_prime.w[1] == 0) | |
651 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
652 MASK_SIGN)); | |
653 BID_RETURN (res); | |
654 } | |
655 | |
656 #if DECIMAL_CALL_BY_REFERENCE | |
657 void | |
658 bid64_quiet_less (int *pres, UINT64 * px, | |
659 UINT64 * | |
660 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) | |
661 { | |
662 UINT64 x = *px; | |
663 UINT64 y = *py; | |
664 #else | |
665 int | |
666 bid64_quiet_less (UINT64 x, | |
667 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
668 _EXC_INFO_PARAM) { | |
669 #endif | |
670 int res; | |
671 int exp_x, exp_y; | |
672 UINT64 sig_x, sig_y; | |
673 UINT128 sig_n_prime; | |
674 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
675 | |
676 // NaN (CASE1) | |
677 // if either number is NAN, the comparison is unordered : return 0 | |
678 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
679 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
680 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
681 } | |
682 res = 0; | |
683 BID_RETURN (res); | |
684 } | |
685 // SIMPLE (CASE2) | |
686 // if all the bits are the same, these numbers are equal. | |
687 if (x == y) { | |
688 res = 0; | |
689 BID_RETURN (res); | |
690 } | |
691 // INFINITY (CASE3) | |
692 if ((x & MASK_INF) == MASK_INF) { | |
693 // if x==neg_inf, { res = (y == neg_inf)?0:1; BID_RETURN (res) } | |
694 if ((x & MASK_SIGN) == MASK_SIGN) { | |
695 // x is -inf, so it is less than y unless y is -inf | |
696 res = (((y & MASK_INF) != MASK_INF) | |
697 || (y & MASK_SIGN) != MASK_SIGN); | |
698 BID_RETURN (res); | |
699 } else { | |
700 // x is pos_inf, no way for it to be less than y | |
701 res = 0; | |
702 BID_RETURN (res); | |
703 } | |
704 } else if ((y & MASK_INF) == MASK_INF) { | |
705 // x is finite, so: | |
706 // if y is +inf, x<y | |
707 // if y is -inf, x>y | |
708 res = ((y & MASK_SIGN) != MASK_SIGN); | |
709 BID_RETURN (res); | |
710 } | |
711 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
712 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
713 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
714 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
715 if (sig_x > 9999999999999999ull) { | |
716 non_canon_x = 1; | |
717 } else { | |
718 non_canon_x = 0; | |
719 } | |
720 } else { | |
721 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
722 sig_x = (x & MASK_BINARY_SIG1); | |
723 non_canon_x = 0; | |
724 } | |
725 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
726 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
727 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
728 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
729 if (sig_y > 9999999999999999ull) { | |
730 non_canon_y = 1; | |
731 } else { | |
732 non_canon_y = 0; | |
733 } | |
734 } else { | |
735 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
736 sig_y = (y & MASK_BINARY_SIG1); | |
737 non_canon_y = 0; | |
738 } | |
739 // ZERO (CASE4) | |
740 // some properties: | |
741 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
742 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
743 // therefore ignore the exponent field | |
744 // (Any non-canonical # is considered 0) | |
745 if (non_canon_x || sig_x == 0) { | |
746 x_is_zero = 1; | |
747 } | |
748 if (non_canon_y || sig_y == 0) { | |
749 y_is_zero = 1; | |
750 } | |
751 if (x_is_zero && y_is_zero) { | |
752 // if both numbers are zero, they are equal | |
753 res = 0; | |
754 BID_RETURN (res); | |
755 } else if (x_is_zero) { | |
756 // if x is zero, it is lessthan if Y is positive | |
757 res = ((y & MASK_SIGN) != MASK_SIGN); | |
758 BID_RETURN (res); | |
759 } else if (y_is_zero) { | |
760 // if y is zero, X is less if it is negative | |
761 res = ((x & MASK_SIGN) == MASK_SIGN); | |
762 BID_RETURN (res); | |
763 } | |
764 // OPPOSITE SIGN (CASE5) | |
765 // now, if the sign bits differ, x is less than if y is positive | |
766 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
767 res = ((y & MASK_SIGN) != MASK_SIGN); | |
768 BID_RETURN (res); | |
769 } | |
770 // REDUNDANT REPRESENTATIONS (CASE6) | |
771 // if both components are either bigger or smaller, | |
772 // it is clear what needs to be done | |
773 if (sig_x > sig_y && exp_x >= exp_y) { | |
774 res = ((x & MASK_SIGN) == MASK_SIGN); | |
775 BID_RETURN (res); | |
776 } | |
777 if (sig_x < sig_y && exp_x <= exp_y) { | |
778 res = ((x & MASK_SIGN) != MASK_SIGN); | |
779 BID_RETURN (res); | |
780 } | |
781 // if exp_x is 15 greater than exp_y, no need for compensation | |
782 if (exp_x - exp_y > 15) { | |
783 res = ((x & MASK_SIGN) == MASK_SIGN); | |
784 // difference cannot be greater than 10^15 | |
785 BID_RETURN (res); | |
786 } | |
787 // if exp_x is 15 less than exp_y, no need for compensation | |
788 if (exp_y - exp_x > 15) { | |
789 res = ((x & MASK_SIGN) != MASK_SIGN); | |
790 BID_RETURN (res); | |
791 } | |
792 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
793 if (exp_x > exp_y) { // to simplify the loop below, | |
794 // otherwise adjust the x significand upwards | |
795 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
796 mult_factor[exp_x - exp_y]); | |
797 // return 0 if values are equal | |
798 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
799 res = 0; | |
800 BID_RETURN (res); | |
801 } | |
802 // if postitive, return whichever significand abs is smaller | |
803 // (converse if negative) | |
804 res = (((sig_n_prime.w[1] == 0) | |
805 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
806 MASK_SIGN)); | |
807 BID_RETURN (res); | |
808 } | |
809 // adjust the y significand upwards | |
810 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
811 mult_factor[exp_y - exp_x]); | |
812 // return 0 if values are equal | |
813 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
814 res = 0; | |
815 BID_RETURN (res); | |
816 } | |
817 // if positive, return whichever significand abs is smaller | |
818 // (converse if negative) | |
819 res = (((sig_n_prime.w[1] > 0) | |
820 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
821 MASK_SIGN)); | |
822 BID_RETURN (res); | |
823 } | |
824 | |
825 #if DECIMAL_CALL_BY_REFERENCE | |
826 void | |
827 bid64_quiet_less_equal (int *pres, UINT64 * px, | |
828 UINT64 * | |
829 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
830 _EXC_INFO_PARAM) { | |
831 UINT64 x = *px; | |
832 UINT64 y = *py; | |
833 #else | |
834 int | |
835 bid64_quiet_less_equal (UINT64 x, | |
836 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
837 _EXC_INFO_PARAM) { | |
838 #endif | |
839 int res; | |
840 int exp_x, exp_y; | |
841 UINT64 sig_x, sig_y; | |
842 UINT128 sig_n_prime; | |
843 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
844 | |
845 // NaN (CASE1) | |
846 // if either number is NAN, the comparison is unordered, rather than equal : | |
847 // return 0 | |
848 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
849 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
850 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
851 } | |
852 res = 0; | |
853 BID_RETURN (res); | |
854 } | |
855 // SIMPLE (CASE2) | |
856 // if all the bits are the same, these numbers are equal (LESSEQUAL). | |
857 if (x == y) { | |
858 res = 1; | |
859 BID_RETURN (res); | |
860 } | |
861 // INFINITY (CASE3) | |
862 if ((x & MASK_INF) == MASK_INF) { | |
863 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
864 // if x is neg infinity, it must be lessthan or equal to y return 1 | |
865 res = 1; | |
866 BID_RETURN (res); | |
867 } else { | |
868 // x is pos infinity, it is greater, unless y is positive infinity => | |
869 // return y==pos_infinity | |
870 res = !(((y & MASK_INF) != MASK_INF) | |
871 || ((y & MASK_SIGN) == MASK_SIGN)); | |
872 BID_RETURN (res); | |
873 } | |
874 } else if ((y & MASK_INF) == MASK_INF) { | |
875 // x is finite, so if y is positive infinity, then x is less, return 1 | |
876 // if y is negative infinity, then x is greater, return 0 | |
877 res = ((y & MASK_SIGN) != MASK_SIGN); | |
878 BID_RETURN (res); | |
879 } | |
880 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
881 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
882 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
883 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
884 if (sig_x > 9999999999999999ull) { | |
885 non_canon_x = 1; | |
886 } else { | |
887 non_canon_x = 0; | |
888 } | |
889 } else { | |
890 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
891 sig_x = (x & MASK_BINARY_SIG1); | |
892 non_canon_x = 0; | |
893 } | |
894 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
895 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
896 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
897 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
898 if (sig_y > 9999999999999999ull) { | |
899 non_canon_y = 1; | |
900 } else { | |
901 non_canon_y = 0; | |
902 } | |
903 } else { | |
904 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
905 sig_y = (y & MASK_BINARY_SIG1); | |
906 non_canon_y = 0; | |
907 } | |
908 // ZERO (CASE4) | |
909 // some properties: | |
910 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
911 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
912 // therefore ignore the exponent field | |
913 // (Any non-canonical # is considered 0) | |
914 if (non_canon_x || sig_x == 0) { | |
915 x_is_zero = 1; | |
916 } | |
917 if (non_canon_y || sig_y == 0) { | |
918 y_is_zero = 1; | |
919 } | |
920 if (x_is_zero && y_is_zero) { | |
921 // if both numbers are zero, they are equal -> return 1 | |
922 res = 1; | |
923 BID_RETURN (res); | |
924 } else if (x_is_zero) { | |
925 // if x is zero, it is lessthan if Y is positive | |
926 res = ((y & MASK_SIGN) != MASK_SIGN); | |
927 BID_RETURN (res); | |
928 } else if (y_is_zero) { | |
929 // if y is zero, X is less if it is negative | |
930 res = ((x & MASK_SIGN) == MASK_SIGN); | |
931 BID_RETURN (res); | |
932 } | |
933 // OPPOSITE SIGN (CASE5) | |
934 // now, if the sign bits differ, x is less than if y is positive | |
935 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
936 res = ((y & MASK_SIGN) != MASK_SIGN); | |
937 BID_RETURN (res); | |
938 } | |
939 // REDUNDANT REPRESENTATIONS (CASE6) | |
940 // if both components are either bigger or smaller | |
941 if (sig_x > sig_y && exp_x >= exp_y) { | |
942 res = ((x & MASK_SIGN) == MASK_SIGN); | |
943 BID_RETURN (res); | |
944 } | |
945 if (sig_x < sig_y && exp_x <= exp_y) { | |
946 res = ((x & MASK_SIGN) != MASK_SIGN); | |
947 BID_RETURN (res); | |
948 } | |
949 // if exp_x is 15 greater than exp_y, no need for compensation | |
950 if (exp_x - exp_y > 15) { | |
951 res = ((x & MASK_SIGN) == MASK_SIGN); | |
952 // difference cannot be greater than 10^15 | |
953 BID_RETURN (res); | |
954 } | |
955 // if exp_x is 15 less than exp_y, no need for compensation | |
956 if (exp_y - exp_x > 15) { | |
957 res = ((x & MASK_SIGN) != MASK_SIGN); | |
958 BID_RETURN (res); | |
959 } | |
960 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
961 if (exp_x > exp_y) { // to simplify the loop below, | |
962 // otherwise adjust the x significand upwards | |
963 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
964 mult_factor[exp_x - exp_y]); | |
965 // return 1 if values are equal | |
966 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
967 res = 1; | |
968 BID_RETURN (res); | |
969 } | |
970 // if postitive, return whichever significand abs is smaller | |
971 // (converse if negative) | |
972 res = (((sig_n_prime.w[1] == 0) | |
973 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
974 MASK_SIGN)); | |
975 BID_RETURN (res); | |
976 } | |
977 // adjust the y significand upwards | |
978 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
979 mult_factor[exp_y - exp_x]); | |
980 // return 1 if values are equal | |
981 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
982 res = 1; | |
983 BID_RETURN (res); | |
984 } | |
985 // if positive, return whichever significand abs is smaller | |
986 // (converse if negative) | |
987 res = (((sig_n_prime.w[1] > 0) | |
988 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
989 MASK_SIGN)); | |
990 BID_RETURN (res); | |
991 } | |
992 | |
993 #if DECIMAL_CALL_BY_REFERENCE | |
994 void | |
995 bid64_quiet_less_unordered (int *pres, UINT64 * px, | |
996 UINT64 * | |
997 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
998 _EXC_INFO_PARAM) { | |
999 UINT64 x = *px; | |
1000 UINT64 y = *py; | |
1001 #else | |
1002 int | |
1003 bid64_quiet_less_unordered (UINT64 x, | |
1004 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1005 _EXC_INFO_PARAM) { | |
1006 #endif | |
1007 int res; | |
1008 int exp_x, exp_y; | |
1009 UINT64 sig_x, sig_y; | |
1010 UINT128 sig_n_prime; | |
1011 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
1012 | |
1013 // NaN (CASE1) | |
1014 // if either number is NAN, the comparison is unordered : return 0 | |
1015 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1016 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1017 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1018 } | |
1019 res = 1; | |
1020 BID_RETURN (res); | |
1021 } | |
1022 // SIMPLE (CASE2) | |
1023 // if all the bits are the same, these numbers are equal. | |
1024 if (x == y) { | |
1025 res = 0; | |
1026 BID_RETURN (res); | |
1027 } | |
1028 // INFINITY (CASE3) | |
1029 if ((x & MASK_INF) == MASK_INF) { | |
1030 // if x==neg_inf, { res = (y == neg_inf)?0:1; BID_RETURN (res) } | |
1031 if ((x & MASK_SIGN) == MASK_SIGN) { | |
1032 // x is -inf, so it is less than y unless y is -inf | |
1033 res = (((y & MASK_INF) != MASK_INF) | |
1034 || (y & MASK_SIGN) != MASK_SIGN); | |
1035 BID_RETURN (res); | |
1036 } else { | |
1037 // x is pos_inf, no way for it to be less than y | |
1038 res = 0; | |
1039 BID_RETURN (res); | |
1040 } | |
1041 } else if ((y & MASK_INF) == MASK_INF) { | |
1042 // x is finite, so: | |
1043 // if y is +inf, x<y | |
1044 // if y is -inf, x>y | |
1045 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1046 BID_RETURN (res); | |
1047 } | |
1048 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1049 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1050 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1051 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1052 if (sig_x > 9999999999999999ull) { | |
1053 non_canon_x = 1; | |
1054 } else { | |
1055 non_canon_x = 0; | |
1056 } | |
1057 } else { | |
1058 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1059 sig_x = (x & MASK_BINARY_SIG1); | |
1060 non_canon_x = 0; | |
1061 } | |
1062 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1063 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1064 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1065 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1066 if (sig_y > 9999999999999999ull) { | |
1067 non_canon_y = 1; | |
1068 } else { | |
1069 non_canon_y = 0; | |
1070 } | |
1071 } else { | |
1072 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1073 sig_y = (y & MASK_BINARY_SIG1); | |
1074 non_canon_y = 0; | |
1075 } | |
1076 // ZERO (CASE4) | |
1077 // some properties: | |
1078 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
1079 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1080 // therefore ignore the exponent field | |
1081 // (Any non-canonical # is considered 0) | |
1082 if (non_canon_x || sig_x == 0) { | |
1083 x_is_zero = 1; | |
1084 } | |
1085 if (non_canon_y || sig_y == 0) { | |
1086 y_is_zero = 1; | |
1087 } | |
1088 if (x_is_zero && y_is_zero) { | |
1089 // if both numbers are zero, they are equal | |
1090 res = 0; | |
1091 BID_RETURN (res); | |
1092 } else if (x_is_zero) { | |
1093 // if x is zero, it is lessthan if Y is positive | |
1094 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1095 BID_RETURN (res); | |
1096 } else if (y_is_zero) { | |
1097 // if y is zero, X is less if it is negative | |
1098 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1099 BID_RETURN (res); | |
1100 } | |
1101 // OPPOSITE SIGN (CASE5) | |
1102 // now, if the sign bits differ, x is less than if y is positive | |
1103 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
1104 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1105 BID_RETURN (res); | |
1106 } | |
1107 // REDUNDANT REPRESENTATIONS (CASE6) | |
1108 // if both components are either bigger or smaller | |
1109 if (sig_x > sig_y && exp_x >= exp_y) { | |
1110 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1111 BID_RETURN (res); | |
1112 } | |
1113 if (sig_x < sig_y && exp_x <= exp_y) { | |
1114 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1115 BID_RETURN (res); | |
1116 } | |
1117 // if exp_x is 15 greater than exp_y, no need for compensation | |
1118 if (exp_x - exp_y > 15) { | |
1119 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1120 // difference cannot be greater than 10^15 | |
1121 BID_RETURN (res); | |
1122 } | |
1123 // if exp_x is 15 less than exp_y, no need for compensation | |
1124 if (exp_y - exp_x > 15) { | |
1125 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1126 BID_RETURN (res); | |
1127 } | |
1128 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
1129 if (exp_x > exp_y) { // to simplify the loop below, | |
1130 // otherwise adjust the x significand upwards | |
1131 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
1132 mult_factor[exp_x - exp_y]); | |
1133 // return 0 if values are equal | |
1134 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
1135 res = 0; | |
1136 BID_RETURN (res); | |
1137 } | |
1138 // if postitive, return whichever significand abs is smaller | |
1139 // (converse if negative) | |
1140 res = (((sig_n_prime.w[1] == 0) | |
1141 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
1142 MASK_SIGN)); | |
1143 BID_RETURN (res); | |
1144 } | |
1145 // adjust the y significand upwards | |
1146 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
1147 mult_factor[exp_y - exp_x]); | |
1148 // return 0 if values are equal | |
1149 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
1150 res = 0; | |
1151 BID_RETURN (res); | |
1152 } | |
1153 // if positive, return whichever significand abs is smaller | |
1154 // (converse if negative) | |
1155 res = (((sig_n_prime.w[1] > 0) | |
1156 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
1157 MASK_SIGN)); | |
1158 BID_RETURN (res); | |
1159 } | |
1160 | |
1161 #if DECIMAL_CALL_BY_REFERENCE | |
1162 void | |
1163 bid64_quiet_not_equal (int *pres, UINT64 * px, | |
1164 UINT64 * | |
1165 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1166 _EXC_INFO_PARAM) { | |
1167 UINT64 x = *px; | |
1168 UINT64 y = *py; | |
1169 #else | |
1170 int | |
1171 bid64_quiet_not_equal (UINT64 x, | |
1172 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1173 _EXC_INFO_PARAM) { | |
1174 #endif | |
1175 int res; | |
1176 int exp_x, exp_y, exp_t; | |
1177 UINT64 sig_x, sig_y, sig_t; | |
1178 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y, lcv; | |
1179 | |
1180 // NaN (CASE1) | |
1181 // if either number is NAN, the comparison is unordered, | |
1182 // rather than equal : return 1 | |
1183 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1184 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1185 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1186 } | |
1187 res = 1; | |
1188 BID_RETURN (res); | |
1189 } | |
1190 // SIMPLE (CASE2) | |
1191 // if all the bits are the same, these numbers are equivalent. | |
1192 if (x == y) { | |
1193 res = 0; | |
1194 BID_RETURN (res); | |
1195 } | |
1196 // INFINITY (CASE3) | |
1197 if (((x & MASK_INF) == MASK_INF) && ((y & MASK_INF) == MASK_INF)) { | |
1198 res = (((x ^ y) & MASK_SIGN) == MASK_SIGN); | |
1199 BID_RETURN (res); | |
1200 } | |
1201 // ONE INFINITY (CASE3') | |
1202 if (((x & MASK_INF) == MASK_INF) || ((y & MASK_INF) == MASK_INF)) { | |
1203 res = 1; | |
1204 BID_RETURN (res); | |
1205 } | |
1206 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1207 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1208 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1209 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1210 if (sig_x > 9999999999999999ull) { | |
1211 non_canon_x = 1; | |
1212 } else { | |
1213 non_canon_x = 0; | |
1214 } | |
1215 } else { | |
1216 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1217 sig_x = (x & MASK_BINARY_SIG1); | |
1218 non_canon_x = 0; | |
1219 } | |
1220 | |
1221 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1222 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1223 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1224 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1225 if (sig_y > 9999999999999999ull) { | |
1226 non_canon_y = 1; | |
1227 } else { | |
1228 non_canon_y = 0; | |
1229 } | |
1230 } else { | |
1231 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1232 sig_y = (y & MASK_BINARY_SIG1); | |
1233 non_canon_y = 0; | |
1234 } | |
1235 | |
1236 // ZERO (CASE4) | |
1237 // some properties: | |
1238 // (+ZERO==-ZERO) => therefore ignore the sign | |
1239 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1240 // therefore ignore the exponent field | |
1241 // (Any non-canonical # is considered 0) | |
1242 if (non_canon_x || sig_x == 0) { | |
1243 x_is_zero = 1; | |
1244 } | |
1245 if (non_canon_y || sig_y == 0) { | |
1246 y_is_zero = 1; | |
1247 } | |
1248 | |
1249 if (x_is_zero && y_is_zero) { | |
1250 res = 0; | |
1251 BID_RETURN (res); | |
1252 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) { | |
1253 res = 1; | |
1254 BID_RETURN (res); | |
1255 } | |
1256 // OPPOSITE SIGN (CASE5) | |
1257 // now, if the sign bits differ => not equal : return 1 | |
1258 if ((x ^ y) & MASK_SIGN) { | |
1259 res = 1; | |
1260 BID_RETURN (res); | |
1261 } | |
1262 // REDUNDANT REPRESENTATIONS (CASE6) | |
1263 if (exp_x > exp_y) { // to simplify the loop below, | |
1264 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y, | |
1265 SWAP (sig_x, sig_y, sig_t); // and the smaller exp in x | |
1266 } | |
1267 | |
1268 if (exp_y - exp_x > 15) { | |
1269 res = 1; | |
1270 BID_RETURN (res); | |
1271 } | |
1272 // difference cannot be greater than 10^16 | |
1273 | |
1274 for (lcv = 0; lcv < (exp_y - exp_x); lcv++) { | |
1275 | |
1276 // recalculate y's significand upwards | |
1277 sig_y = sig_y * 10; | |
1278 if (sig_y > 9999999999999999ull) { | |
1279 res = 1; | |
1280 BID_RETURN (res); | |
1281 } | |
1282 } | |
1283 | |
1284 { | |
1285 res = sig_y != sig_x; | |
1286 BID_RETURN (res); | |
1287 } | |
1288 | |
1289 } | |
1290 | |
1291 #if DECIMAL_CALL_BY_REFERENCE | |
1292 void | |
1293 bid64_quiet_not_greater (int *pres, UINT64 * px, | |
1294 UINT64 * | |
1295 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1296 _EXC_INFO_PARAM) { | |
1297 UINT64 x = *px; | |
1298 UINT64 y = *py; | |
1299 #else | |
1300 int | |
1301 bid64_quiet_not_greater (UINT64 x, | |
1302 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1303 _EXC_INFO_PARAM) { | |
1304 #endif | |
1305 int res; | |
1306 int exp_x, exp_y; | |
1307 UINT64 sig_x, sig_y; | |
1308 UINT128 sig_n_prime; | |
1309 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
1310 | |
1311 // NaN (CASE1) | |
1312 // if either number is NAN, the comparison is unordered, | |
1313 // rather than equal : return 0 | |
1314 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1315 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1316 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1317 } | |
1318 res = 1; | |
1319 BID_RETURN (res); | |
1320 } | |
1321 // SIMPLE (CASE2) | |
1322 // if all the bits are the same, these numbers are equal (LESSEQUAL). | |
1323 if (x == y) { | |
1324 res = 1; | |
1325 BID_RETURN (res); | |
1326 } | |
1327 // INFINITY (CASE3) | |
1328 if ((x & MASK_INF) == MASK_INF) { | |
1329 // if x is neg infinity, it must be lessthan or equal to y return 1 | |
1330 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
1331 res = 1; | |
1332 BID_RETURN (res); | |
1333 } | |
1334 // x is pos infinity, it is greater, unless y is positive | |
1335 // infinity => return y==pos_infinity | |
1336 else { | |
1337 res = !(((y & MASK_INF) != MASK_INF) | |
1338 || ((y & MASK_SIGN) == MASK_SIGN)); | |
1339 BID_RETURN (res); | |
1340 } | |
1341 } else if ((y & MASK_INF) == MASK_INF) { | |
1342 // x is finite, so if y is positive infinity, then x is less, return 1 | |
1343 // if y is negative infinity, then x is greater, return 0 | |
1344 { | |
1345 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1346 BID_RETURN (res); | |
1347 } | |
1348 } | |
1349 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1350 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1351 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1352 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1353 if (sig_x > 9999999999999999ull) { | |
1354 non_canon_x = 1; | |
1355 } else { | |
1356 non_canon_x = 0; | |
1357 } | |
1358 } else { | |
1359 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1360 sig_x = (x & MASK_BINARY_SIG1); | |
1361 non_canon_x = 0; | |
1362 } | |
1363 | |
1364 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1365 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1366 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1367 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1368 if (sig_y > 9999999999999999ull) { | |
1369 non_canon_y = 1; | |
1370 } else { | |
1371 non_canon_y = 0; | |
1372 } | |
1373 } else { | |
1374 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1375 sig_y = (y & MASK_BINARY_SIG1); | |
1376 non_canon_y = 0; | |
1377 } | |
1378 | |
1379 // ZERO (CASE4) | |
1380 // some properties: | |
1381 // (+ZERO==-ZERO) => therefore ignore the sign, and neither | |
1382 // number is greater | |
1383 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1384 // therefore ignore the exponent field | |
1385 // (Any non-canonical # is considered 0) | |
1386 if (non_canon_x || sig_x == 0) { | |
1387 x_is_zero = 1; | |
1388 } | |
1389 if (non_canon_y || sig_y == 0) { | |
1390 y_is_zero = 1; | |
1391 } | |
1392 // if both numbers are zero, they are equal -> return 1 | |
1393 if (x_is_zero && y_is_zero) { | |
1394 res = 1; | |
1395 BID_RETURN (res); | |
1396 } | |
1397 // if x is zero, it is lessthan if Y is positive | |
1398 else if (x_is_zero) { | |
1399 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1400 BID_RETURN (res); | |
1401 } | |
1402 // if y is zero, X is less if it is negative | |
1403 else if (y_is_zero) { | |
1404 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1405 BID_RETURN (res); | |
1406 } | |
1407 // OPPOSITE SIGN (CASE5) | |
1408 // now, if the sign bits differ, x is less than if y is positive | |
1409 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
1410 res = ((y & MASK_SIGN) != MASK_SIGN); | |
1411 BID_RETURN (res); | |
1412 } | |
1413 // REDUNDANT REPRESENTATIONS (CASE6) | |
1414 // if both components are either bigger or smaller | |
1415 if (sig_x > sig_y && exp_x >= exp_y) { | |
1416 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1417 BID_RETURN (res); | |
1418 } | |
1419 if (sig_x < sig_y && exp_x <= exp_y) { | |
1420 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1421 BID_RETURN (res); | |
1422 } | |
1423 // if exp_x is 15 greater than exp_y, no need for compensation | |
1424 if (exp_x - exp_y > 15) { | |
1425 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1426 BID_RETURN (res); | |
1427 } | |
1428 // difference cannot be greater than 10^15 | |
1429 | |
1430 // if exp_x is 15 less than exp_y, no need for compensation | |
1431 if (exp_y - exp_x > 15) { | |
1432 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1433 BID_RETURN (res); | |
1434 } | |
1435 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
1436 if (exp_x > exp_y) { // to simplify the loop below, | |
1437 | |
1438 // otherwise adjust the x significand upwards | |
1439 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
1440 mult_factor[exp_x - exp_y]); | |
1441 | |
1442 // return 1 if values are equal | |
1443 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
1444 res = 1; | |
1445 BID_RETURN (res); | |
1446 } | |
1447 // if postitive, return whichever significand abs is smaller | |
1448 // (converse if negative) | |
1449 { | |
1450 res = (((sig_n_prime.w[1] == 0) | |
1451 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
1452 MASK_SIGN)); | |
1453 BID_RETURN (res); | |
1454 } | |
1455 } | |
1456 // adjust the y significand upwards | |
1457 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
1458 mult_factor[exp_y - exp_x]); | |
1459 | |
1460 // return 1 if values are equal | |
1461 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
1462 res = 1; | |
1463 BID_RETURN (res); | |
1464 } | |
1465 // if positive, return whichever significand abs is smaller | |
1466 // (converse if negative) | |
1467 { | |
1468 res = (((sig_n_prime.w[1] > 0) | |
1469 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
1470 MASK_SIGN)); | |
1471 BID_RETURN (res); | |
1472 } | |
1473 } | |
1474 | |
1475 #if DECIMAL_CALL_BY_REFERENCE | |
1476 void | |
1477 bid64_quiet_not_less (int *pres, UINT64 * px, | |
1478 UINT64 * | |
1479 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1480 _EXC_INFO_PARAM) { | |
1481 UINT64 x = *px; | |
1482 UINT64 y = *py; | |
1483 #else | |
1484 int | |
1485 bid64_quiet_not_less (UINT64 x, | |
1486 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1487 _EXC_INFO_PARAM) { | |
1488 #endif | |
1489 int res; | |
1490 int exp_x, exp_y; | |
1491 UINT64 sig_x, sig_y; | |
1492 UINT128 sig_n_prime; | |
1493 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
1494 | |
1495 // NaN (CASE1) | |
1496 // if either number is NAN, the comparison is unordered : return 1 | |
1497 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1498 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1499 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1500 } | |
1501 res = 1; | |
1502 BID_RETURN (res); | |
1503 } | |
1504 // SIMPLE (CASE2) | |
1505 // if all the bits are the same, these numbers are equal. | |
1506 if (x == y) { | |
1507 res = 1; | |
1508 BID_RETURN (res); | |
1509 } | |
1510 // INFINITY (CASE3) | |
1511 if ((x & MASK_INF) == MASK_INF) { | |
1512 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } | |
1513 if ((x & MASK_SIGN) == MASK_SIGN) | |
1514 // x is -inf, so it is less than y unless y is -inf | |
1515 { | |
1516 res = (((y & MASK_INF) == MASK_INF) | |
1517 && (y & MASK_SIGN) == MASK_SIGN); | |
1518 BID_RETURN (res); | |
1519 } else | |
1520 // x is pos_inf, no way for it to be less than y | |
1521 { | |
1522 res = 1; | |
1523 BID_RETURN (res); | |
1524 } | |
1525 } else if ((y & MASK_INF) == MASK_INF) { | |
1526 // x is finite, so: | |
1527 // if y is +inf, x<y | |
1528 // if y is -inf, x>y | |
1529 { | |
1530 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1531 BID_RETURN (res); | |
1532 } | |
1533 } | |
1534 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1535 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1536 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1537 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1538 if (sig_x > 9999999999999999ull) { | |
1539 non_canon_x = 1; | |
1540 } else { | |
1541 non_canon_x = 0; | |
1542 } | |
1543 } else { | |
1544 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1545 sig_x = (x & MASK_BINARY_SIG1); | |
1546 non_canon_x = 0; | |
1547 } | |
1548 | |
1549 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1550 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1551 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1552 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1553 if (sig_y > 9999999999999999ull) { | |
1554 non_canon_y = 1; | |
1555 } else { | |
1556 non_canon_y = 0; | |
1557 } | |
1558 } else { | |
1559 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1560 sig_y = (y & MASK_BINARY_SIG1); | |
1561 non_canon_y = 0; | |
1562 } | |
1563 | |
1564 // ZERO (CASE4) | |
1565 // some properties: | |
1566 // (+ZERO==-ZERO) => therefore ignore the sign, and neither | |
1567 // number is greater | |
1568 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1569 // therefore ignore the exponent field | |
1570 // (Any non-canonical # is considered 0) | |
1571 if (non_canon_x || sig_x == 0) { | |
1572 x_is_zero = 1; | |
1573 } | |
1574 if (non_canon_y || sig_y == 0) { | |
1575 y_is_zero = 1; | |
1576 } | |
1577 // if both numbers are zero, they are equal | |
1578 if (x_is_zero && y_is_zero) { | |
1579 res = 1; | |
1580 BID_RETURN (res); | |
1581 } | |
1582 // if x is zero, it is lessthan if Y is positive | |
1583 else if (x_is_zero) { | |
1584 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1585 BID_RETURN (res); | |
1586 } | |
1587 // if y is zero, X is less if it is negative | |
1588 else if (y_is_zero) { | |
1589 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1590 BID_RETURN (res); | |
1591 } | |
1592 // OPPOSITE SIGN (CASE5) | |
1593 // now, if the sign bits differ, x is less than if y is positive | |
1594 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
1595 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1596 BID_RETURN (res); | |
1597 } | |
1598 // REDUNDANT REPRESENTATIONS (CASE6) | |
1599 // if both components are either bigger or smaller | |
1600 if (sig_x > sig_y && exp_x >= exp_y) { | |
1601 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1602 BID_RETURN (res); | |
1603 } | |
1604 if (sig_x < sig_y && exp_x <= exp_y) { | |
1605 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1606 BID_RETURN (res); | |
1607 } | |
1608 // if exp_x is 15 greater than exp_y, no need for compensation | |
1609 if (exp_x - exp_y > 15) { | |
1610 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1611 BID_RETURN (res); | |
1612 } | |
1613 // difference cannot be greater than 10^15 | |
1614 | |
1615 // if exp_x is 15 less than exp_y, no need for compensation | |
1616 if (exp_y - exp_x > 15) { | |
1617 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1618 BID_RETURN (res); | |
1619 } | |
1620 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
1621 if (exp_x > exp_y) { // to simplify the loop below, | |
1622 | |
1623 // otherwise adjust the x significand upwards | |
1624 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
1625 mult_factor[exp_x - exp_y]); | |
1626 | |
1627 // return 0 if values are equal | |
1628 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
1629 res = 1; | |
1630 BID_RETURN (res); | |
1631 } | |
1632 // if postitive, return whichever significand abs is smaller | |
1633 // (converse if negative) | |
1634 { | |
1635 res = (((sig_n_prime.w[1] == 0) | |
1636 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) != | |
1637 MASK_SIGN)); | |
1638 BID_RETURN (res); | |
1639 } | |
1640 } | |
1641 // adjust the y significand upwards | |
1642 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
1643 mult_factor[exp_y - exp_x]); | |
1644 | |
1645 // return 0 if values are equal | |
1646 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
1647 res = 1; | |
1648 BID_RETURN (res); | |
1649 } | |
1650 // if positive, return whichever significand abs is smaller | |
1651 // (converse if negative) | |
1652 { | |
1653 res = (((sig_n_prime.w[1] > 0) | |
1654 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) != | |
1655 MASK_SIGN)); | |
1656 BID_RETURN (res); | |
1657 } | |
1658 } | |
1659 | |
1660 #if DECIMAL_CALL_BY_REFERENCE | |
1661 void | |
1662 bid64_quiet_ordered (int *pres, UINT64 * px, | |
1663 UINT64 * | |
1664 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1665 _EXC_INFO_PARAM) { | |
1666 UINT64 x = *px; | |
1667 UINT64 y = *py; | |
1668 #else | |
1669 int | |
1670 bid64_quiet_ordered (UINT64 x, | |
1671 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1672 _EXC_INFO_PARAM) { | |
1673 #endif | |
1674 int res; | |
1675 | |
1676 // NaN (CASE1) | |
1677 // if either number is NAN, the comparison is ordered, rather than equal : return 0 | |
1678 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1679 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1680 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1681 } | |
1682 res = 0; | |
1683 BID_RETURN (res); | |
1684 } else { | |
1685 res = 1; | |
1686 BID_RETURN (res); | |
1687 } | |
1688 } | |
1689 | |
1690 #if DECIMAL_CALL_BY_REFERENCE | |
1691 void | |
1692 bid64_quiet_unordered (int *pres, UINT64 * px, | |
1693 UINT64 * | |
1694 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1695 _EXC_INFO_PARAM) { | |
1696 UINT64 x = *px; | |
1697 UINT64 y = *py; | |
1698 #else | |
1699 int | |
1700 bid64_quiet_unordered (UINT64 x, | |
1701 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1702 _EXC_INFO_PARAM) { | |
1703 #endif | |
1704 int res; | |
1705 | |
1706 // NaN (CASE1) | |
1707 // if either number is NAN, the comparison is unordered, | |
1708 // rather than equal : return 0 | |
1709 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1710 if ((x & MASK_SNAN) == MASK_SNAN || (y & MASK_SNAN) == MASK_SNAN) { | |
1711 *pfpsf |= INVALID_EXCEPTION; // set exception if sNaN | |
1712 } | |
1713 res = 1; | |
1714 BID_RETURN (res); | |
1715 } else { | |
1716 res = 0; | |
1717 BID_RETURN (res); | |
1718 } | |
1719 } | |
1720 | |
1721 #if DECIMAL_CALL_BY_REFERENCE | |
1722 void | |
1723 bid64_signaling_greater (int *pres, UINT64 * px, | |
1724 UINT64 * | |
1725 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1726 _EXC_INFO_PARAM) { | |
1727 UINT64 x = *px; | |
1728 UINT64 y = *py; | |
1729 #else | |
1730 int | |
1731 bid64_signaling_greater (UINT64 x, | |
1732 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1733 _EXC_INFO_PARAM) { | |
1734 #endif | |
1735 int res; | |
1736 int exp_x, exp_y; | |
1737 UINT64 sig_x, sig_y; | |
1738 UINT128 sig_n_prime; | |
1739 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
1740 | |
1741 // NaN (CASE1) | |
1742 // if either number is NAN, the comparison is unordered, | |
1743 // rather than equal : return 0 | |
1744 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1745 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
1746 res = 0; | |
1747 BID_RETURN (res); | |
1748 } | |
1749 // SIMPLE (CASE2) | |
1750 // if all the bits are the same, these numbers are equal (not Greater). | |
1751 if (x == y) { | |
1752 res = 0; | |
1753 BID_RETURN (res); | |
1754 } | |
1755 // INFINITY (CASE3) | |
1756 if ((x & MASK_INF) == MASK_INF) { | |
1757 // if x is neg infinity, there is no way it is greater than y, return 0 | |
1758 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
1759 res = 0; | |
1760 BID_RETURN (res); | |
1761 } | |
1762 // x is pos infinity, it is greater, | |
1763 // unless y is positive infinity => return y!=pos_infinity | |
1764 else { | |
1765 res = (((y & MASK_INF) != MASK_INF) | |
1766 || ((y & MASK_SIGN) == MASK_SIGN)); | |
1767 BID_RETURN (res); | |
1768 } | |
1769 } else if ((y & MASK_INF) == MASK_INF) { | |
1770 // x is finite, so if y is positive infinity, then x is less, return 0 | |
1771 // if y is negative infinity, then x is greater, return 1 | |
1772 { | |
1773 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1774 BID_RETURN (res); | |
1775 } | |
1776 } | |
1777 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1778 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1779 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1780 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1781 if (sig_x > 9999999999999999ull) { | |
1782 non_canon_x = 1; | |
1783 } else { | |
1784 non_canon_x = 0; | |
1785 } | |
1786 } else { | |
1787 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1788 sig_x = (x & MASK_BINARY_SIG1); | |
1789 non_canon_x = 0; | |
1790 } | |
1791 | |
1792 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1793 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1794 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1795 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1796 if (sig_y > 9999999999999999ull) { | |
1797 non_canon_y = 1; | |
1798 } else { | |
1799 non_canon_y = 0; | |
1800 } | |
1801 } else { | |
1802 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1803 sig_y = (y & MASK_BINARY_SIG1); | |
1804 non_canon_y = 0; | |
1805 } | |
1806 | |
1807 // ZERO (CASE4) | |
1808 // some properties: | |
1809 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
1810 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1811 // therefore ignore the exponent field | |
1812 // (Any non-canonical # is considered 0) | |
1813 if (non_canon_x || sig_x == 0) { | |
1814 x_is_zero = 1; | |
1815 } | |
1816 if (non_canon_y || sig_y == 0) { | |
1817 y_is_zero = 1; | |
1818 } | |
1819 // if both numbers are zero, neither is greater => return NOTGREATERTHAN | |
1820 if (x_is_zero && y_is_zero) { | |
1821 res = 0; | |
1822 BID_RETURN (res); | |
1823 } | |
1824 // is x is zero, it is greater if Y is negative | |
1825 else if (x_is_zero) { | |
1826 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1827 BID_RETURN (res); | |
1828 } | |
1829 // is y is zero, X is greater if it is positive | |
1830 else if (y_is_zero) { | |
1831 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1832 BID_RETURN (res); | |
1833 } | |
1834 // OPPOSITE SIGN (CASE5) | |
1835 // now, if the sign bits differ, x is greater if y is negative | |
1836 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
1837 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1838 BID_RETURN (res); | |
1839 } | |
1840 // REDUNDANT REPRESENTATIONS (CASE6) | |
1841 | |
1842 // if both components are either bigger or smaller | |
1843 if (sig_x > sig_y && exp_x >= exp_y) { | |
1844 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1845 BID_RETURN (res); | |
1846 } | |
1847 if (sig_x < sig_y && exp_x <= exp_y) { | |
1848 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1849 BID_RETURN (res); | |
1850 } | |
1851 // if exp_x is 15 greater than exp_y, no need for compensation | |
1852 if (exp_x - exp_y > 15) { | |
1853 res = ((x & MASK_SIGN) != MASK_SIGN); | |
1854 BID_RETURN (res); | |
1855 } | |
1856 // difference cannot be greater than 10^15 | |
1857 | |
1858 // if exp_x is 15 less than exp_y, no need for compensation | |
1859 if (exp_y - exp_x > 15) { | |
1860 res = ((x & MASK_SIGN) == MASK_SIGN); | |
1861 BID_RETURN (res); | |
1862 } | |
1863 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
1864 if (exp_x > exp_y) { // to simplify the loop below, | |
1865 | |
1866 // otherwise adjust the x significand upwards | |
1867 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
1868 mult_factor[exp_x - exp_y]); | |
1869 | |
1870 | |
1871 // if postitive, return whichever significand is larger | |
1872 // (converse if negative) | |
1873 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
1874 res = 0; | |
1875 BID_RETURN (res); | |
1876 } | |
1877 | |
1878 { | |
1879 res = (((sig_n_prime.w[1] > 0) | |
1880 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) == | |
1881 MASK_SIGN)); | |
1882 BID_RETURN (res); | |
1883 } | |
1884 } | |
1885 // adjust the y significand upwards | |
1886 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
1887 mult_factor[exp_y - exp_x]); | |
1888 | |
1889 // if postitive, return whichever significand is larger | |
1890 // (converse if negative) | |
1891 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
1892 res = 0; | |
1893 BID_RETURN (res); | |
1894 } | |
1895 { | |
1896 res = (((sig_n_prime.w[1] == 0) | |
1897 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
1898 MASK_SIGN)); | |
1899 BID_RETURN (res); | |
1900 } | |
1901 } | |
1902 | |
1903 #if DECIMAL_CALL_BY_REFERENCE | |
1904 void | |
1905 bid64_signaling_greater_equal (int *pres, UINT64 * px, | |
1906 UINT64 * | |
1907 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
1908 _EXC_INFO_PARAM) { | |
1909 UINT64 x = *px; | |
1910 UINT64 y = *py; | |
1911 #else | |
1912 int | |
1913 bid64_signaling_greater_equal (UINT64 x, | |
1914 UINT64 y _EXC_FLAGS_PARAM | |
1915 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { | |
1916 #endif | |
1917 int res; | |
1918 int exp_x, exp_y; | |
1919 UINT64 sig_x, sig_y; | |
1920 UINT128 sig_n_prime; | |
1921 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
1922 | |
1923 // NaN (CASE1) | |
1924 // if either number is NAN, the comparison is unordered : return 1 | |
1925 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
1926 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
1927 res = 0; | |
1928 BID_RETURN (res); | |
1929 } | |
1930 // SIMPLE (CASE2) | |
1931 // if all the bits are the same, these numbers are equal. | |
1932 if (x == y) { | |
1933 res = 1; | |
1934 BID_RETURN (res); | |
1935 } | |
1936 // INFINITY (CASE3) | |
1937 if ((x & MASK_INF) == MASK_INF) { | |
1938 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } | |
1939 if ((x & MASK_SIGN) == MASK_SIGN) | |
1940 // x is -inf, so it is less than y unless y is -inf | |
1941 { | |
1942 res = (((y & MASK_INF) == MASK_INF) | |
1943 && (y & MASK_SIGN) == MASK_SIGN); | |
1944 BID_RETURN (res); | |
1945 } else | |
1946 // x is pos_inf, no way for it to be less than y | |
1947 { | |
1948 res = 1; | |
1949 BID_RETURN (res); | |
1950 } | |
1951 } else if ((y & MASK_INF) == MASK_INF) { | |
1952 // x is finite, so: | |
1953 // if y is +inf, x<y | |
1954 // if y is -inf, x>y | |
1955 { | |
1956 res = ((y & MASK_SIGN) == MASK_SIGN); | |
1957 BID_RETURN (res); | |
1958 } | |
1959 } | |
1960 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1961 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1962 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
1963 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1964 if (sig_x > 9999999999999999ull) { | |
1965 non_canon_x = 1; | |
1966 } else { | |
1967 non_canon_x = 0; | |
1968 } | |
1969 } else { | |
1970 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
1971 sig_x = (x & MASK_BINARY_SIG1); | |
1972 non_canon_x = 0; | |
1973 } | |
1974 | |
1975 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
1976 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
1977 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
1978 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
1979 if (sig_y > 9999999999999999ull) { | |
1980 non_canon_y = 1; | |
1981 } else { | |
1982 non_canon_y = 0; | |
1983 } | |
1984 } else { | |
1985 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
1986 sig_y = (y & MASK_BINARY_SIG1); | |
1987 non_canon_y = 0; | |
1988 } | |
1989 | |
1990 // ZERO (CASE4) | |
1991 // some properties: | |
1992 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
1993 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
1994 // therefore ignore the exponent field | |
1995 // (Any non-canonical # is considered 0) | |
1996 if (non_canon_x || sig_x == 0) { | |
1997 x_is_zero = 1; | |
1998 } | |
1999 if (non_canon_y || sig_y == 0) { | |
2000 y_is_zero = 1; | |
2001 } | |
2002 // if both numbers are zero, they are equal | |
2003 if (x_is_zero && y_is_zero) { | |
2004 res = 1; | |
2005 BID_RETURN (res); | |
2006 } | |
2007 // if x is zero, it is lessthan if Y is positive | |
2008 else if (x_is_zero) { | |
2009 res = ((y & MASK_SIGN) == MASK_SIGN); | |
2010 BID_RETURN (res); | |
2011 } | |
2012 // if y is zero, X is less if it is negative | |
2013 else if (y_is_zero) { | |
2014 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2015 BID_RETURN (res); | |
2016 } | |
2017 // OPPOSITE SIGN (CASE5) | |
2018 // now, if the sign bits differ, x is less than if y is positive | |
2019 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2020 res = ((y & MASK_SIGN) == MASK_SIGN); | |
2021 BID_RETURN (res); | |
2022 } | |
2023 // REDUNDANT REPRESENTATIONS (CASE6) | |
2024 // if both components are either bigger or smaller | |
2025 if (sig_x > sig_y && exp_x >= exp_y) { | |
2026 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2027 BID_RETURN (res); | |
2028 } | |
2029 if (sig_x < sig_y && exp_x <= exp_y) { | |
2030 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2031 BID_RETURN (res); | |
2032 } | |
2033 // if exp_x is 15 greater than exp_y, no need for compensation | |
2034 if (exp_x - exp_y > 15) { | |
2035 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2036 BID_RETURN (res); | |
2037 } | |
2038 // difference cannot be greater than 10^15 | |
2039 | |
2040 // if exp_x is 15 less than exp_y, no need for compensation | |
2041 if (exp_y - exp_x > 15) { | |
2042 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2043 BID_RETURN (res); | |
2044 } | |
2045 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2046 if (exp_x > exp_y) { // to simplify the loop below, | |
2047 | |
2048 // otherwise adjust the x significand upwards | |
2049 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2050 mult_factor[exp_x - exp_y]); | |
2051 | |
2052 // return 1 if values are equal | |
2053 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2054 res = 1; | |
2055 BID_RETURN (res); | |
2056 } | |
2057 // if postitive, return whichever significand abs is smaller | |
2058 // (converse if negative) | |
2059 { | |
2060 res = (((sig_n_prime.w[1] == 0) | |
2061 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) != | |
2062 MASK_SIGN)); | |
2063 BID_RETURN (res); | |
2064 } | |
2065 } | |
2066 // adjust the y significand upwards | |
2067 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2068 mult_factor[exp_y - exp_x]); | |
2069 | |
2070 // return 0 if values are equal | |
2071 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2072 res = 1; | |
2073 BID_RETURN (res); | |
2074 } | |
2075 // if positive, return whichever significand abs is smaller | |
2076 // (converse if negative) | |
2077 { | |
2078 res = (((sig_n_prime.w[1] > 0) | |
2079 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) != | |
2080 MASK_SIGN)); | |
2081 BID_RETURN (res); | |
2082 } | |
2083 } | |
2084 | |
2085 #if DECIMAL_CALL_BY_REFERENCE | |
2086 void | |
2087 bid64_signaling_greater_unordered (int *pres, UINT64 * px, | |
2088 UINT64 * | |
2089 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2090 _EXC_INFO_PARAM) { | |
2091 UINT64 x = *px; | |
2092 UINT64 y = *py; | |
2093 #else | |
2094 int | |
2095 bid64_signaling_greater_unordered (UINT64 x, | |
2096 UINT64 y _EXC_FLAGS_PARAM | |
2097 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { | |
2098 #endif | |
2099 int res; | |
2100 int exp_x, exp_y; | |
2101 UINT64 sig_x, sig_y; | |
2102 UINT128 sig_n_prime; | |
2103 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
2104 | |
2105 // NaN (CASE1) | |
2106 // if either number is NAN, the comparison is unordered, | |
2107 // rather than equal : return 0 | |
2108 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
2109 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
2110 res = 1; | |
2111 BID_RETURN (res); | |
2112 } | |
2113 // SIMPLE (CASE2) | |
2114 // if all the bits are the same, these numbers are equal (not Greater). | |
2115 if (x == y) { | |
2116 res = 0; | |
2117 BID_RETURN (res); | |
2118 } | |
2119 // INFINITY (CASE3) | |
2120 if ((x & MASK_INF) == MASK_INF) { | |
2121 // if x is neg infinity, there is no way it is greater than y, return 0 | |
2122 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
2123 res = 0; | |
2124 BID_RETURN (res); | |
2125 } | |
2126 // x is pos infinity, it is greater, | |
2127 // unless y is positive infinity => return y!=pos_infinity | |
2128 else { | |
2129 res = (((y & MASK_INF) != MASK_INF) | |
2130 || ((y & MASK_SIGN) == MASK_SIGN)); | |
2131 BID_RETURN (res); | |
2132 } | |
2133 } else if ((y & MASK_INF) == MASK_INF) { | |
2134 // x is finite, so if y is positive infinity, then x is less, return 0 | |
2135 // if y is negative infinity, then x is greater, return 1 | |
2136 { | |
2137 res = ((y & MASK_SIGN) == MASK_SIGN); | |
2138 BID_RETURN (res); | |
2139 } | |
2140 } | |
2141 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2142 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2143 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
2144 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2145 if (sig_x > 9999999999999999ull) { | |
2146 non_canon_x = 1; | |
2147 } else { | |
2148 non_canon_x = 0; | |
2149 } | |
2150 } else { | |
2151 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
2152 sig_x = (x & MASK_BINARY_SIG1); | |
2153 non_canon_x = 0; | |
2154 } | |
2155 | |
2156 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2157 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2158 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
2159 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2160 if (sig_y > 9999999999999999ull) { | |
2161 non_canon_y = 1; | |
2162 } else { | |
2163 non_canon_y = 0; | |
2164 } | |
2165 } else { | |
2166 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
2167 sig_y = (y & MASK_BINARY_SIG1); | |
2168 non_canon_y = 0; | |
2169 } | |
2170 | |
2171 // ZERO (CASE4) | |
2172 // some properties: | |
2173 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
2174 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
2175 // therefore ignore the exponent field | |
2176 // (Any non-canonical # is considered 0) | |
2177 if (non_canon_x || sig_x == 0) { | |
2178 x_is_zero = 1; | |
2179 } | |
2180 if (non_canon_y || sig_y == 0) { | |
2181 y_is_zero = 1; | |
2182 } | |
2183 // if both numbers are zero, neither is greater => return NOTGREATERTHAN | |
2184 if (x_is_zero && y_is_zero) { | |
2185 res = 0; | |
2186 BID_RETURN (res); | |
2187 } | |
2188 // is x is zero, it is greater if Y is negative | |
2189 else if (x_is_zero) { | |
2190 res = ((y & MASK_SIGN) == MASK_SIGN); | |
2191 BID_RETURN (res); | |
2192 } | |
2193 // is y is zero, X is greater if it is positive | |
2194 else if (y_is_zero) { | |
2195 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2196 BID_RETURN (res); | |
2197 } | |
2198 // OPPOSITE SIGN (CASE5) | |
2199 // now, if the sign bits differ, x is greater if y is negative | |
2200 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2201 res = ((y & MASK_SIGN) == MASK_SIGN); | |
2202 BID_RETURN (res); | |
2203 } | |
2204 // REDUNDANT REPRESENTATIONS (CASE6) | |
2205 | |
2206 // if both components are either bigger or smaller | |
2207 if (sig_x > sig_y && exp_x >= exp_y) { | |
2208 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2209 BID_RETURN (res); | |
2210 } | |
2211 if (sig_x < sig_y && exp_x <= exp_y) { | |
2212 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2213 BID_RETURN (res); | |
2214 } | |
2215 // if exp_x is 15 greater than exp_y, no need for compensation | |
2216 if (exp_x - exp_y > 15) { | |
2217 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2218 BID_RETURN (res); | |
2219 } | |
2220 // difference cannot be greater than 10^15 | |
2221 | |
2222 // if exp_x is 15 less than exp_y, no need for compensation | |
2223 if (exp_y - exp_x > 15) { | |
2224 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2225 BID_RETURN (res); | |
2226 } | |
2227 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2228 if (exp_x > exp_y) { // to simplify the loop below, | |
2229 | |
2230 // otherwise adjust the x significand upwards | |
2231 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2232 mult_factor[exp_x - exp_y]); | |
2233 | |
2234 // if postitive, return whichever significand is larger | |
2235 // (converse if negative) | |
2236 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2237 res = 0; | |
2238 BID_RETURN (res); | |
2239 } | |
2240 | |
2241 { | |
2242 res = (((sig_n_prime.w[1] > 0) | |
2243 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) == | |
2244 MASK_SIGN)); | |
2245 BID_RETURN (res); | |
2246 } | |
2247 } | |
2248 // adjust the y significand upwards | |
2249 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2250 mult_factor[exp_y - exp_x]); | |
2251 | |
2252 // if postitive, return whichever significand is larger | |
2253 // (converse if negative) | |
2254 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2255 res = 0; | |
2256 BID_RETURN (res); | |
2257 } | |
2258 { | |
2259 res = (((sig_n_prime.w[1] == 0) | |
2260 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
2261 MASK_SIGN)); | |
2262 BID_RETURN (res); | |
2263 } | |
2264 } | |
2265 | |
2266 #if DECIMAL_CALL_BY_REFERENCE | |
2267 void | |
2268 bid64_signaling_less (int *pres, UINT64 * px, | |
2269 UINT64 * | |
2270 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2271 _EXC_INFO_PARAM) { | |
2272 UINT64 x = *px; | |
2273 UINT64 y = *py; | |
2274 #else | |
2275 int | |
2276 bid64_signaling_less (UINT64 x, | |
2277 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2278 _EXC_INFO_PARAM) { | |
2279 #endif | |
2280 int res; | |
2281 int exp_x, exp_y; | |
2282 UINT64 sig_x, sig_y; | |
2283 UINT128 sig_n_prime; | |
2284 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
2285 | |
2286 // NaN (CASE1) | |
2287 // if either number is NAN, the comparison is unordered : return 0 | |
2288 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
2289 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
2290 res = 0; | |
2291 BID_RETURN (res); | |
2292 } | |
2293 // SIMPLE (CASE2) | |
2294 // if all the bits are the same, these numbers are equal. | |
2295 if (x == y) { | |
2296 res = 0; | |
2297 BID_RETURN (res); | |
2298 } | |
2299 // INFINITY (CASE3) | |
2300 if ((x & MASK_INF) == MASK_INF) { | |
2301 // if x==neg_inf, { res = (y == neg_inf)?0:1; BID_RETURN (res) } | |
2302 if ((x & MASK_SIGN) == MASK_SIGN) | |
2303 // x is -inf, so it is less than y unless y is -inf | |
2304 { | |
2305 res = (((y & MASK_INF) != MASK_INF) | |
2306 || (y & MASK_SIGN) != MASK_SIGN); | |
2307 BID_RETURN (res); | |
2308 } else | |
2309 // x is pos_inf, no way for it to be less than y | |
2310 { | |
2311 res = 0; | |
2312 BID_RETURN (res); | |
2313 } | |
2314 } else if ((y & MASK_INF) == MASK_INF) { | |
2315 // x is finite, so: | |
2316 // if y is +inf, x<y | |
2317 // if y is -inf, x>y | |
2318 { | |
2319 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2320 BID_RETURN (res); | |
2321 } | |
2322 } | |
2323 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2324 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2325 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
2326 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2327 if (sig_x > 9999999999999999ull) { | |
2328 non_canon_x = 1; | |
2329 } else { | |
2330 non_canon_x = 0; | |
2331 } | |
2332 } else { | |
2333 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
2334 sig_x = (x & MASK_BINARY_SIG1); | |
2335 non_canon_x = 0; | |
2336 } | |
2337 | |
2338 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2339 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2340 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
2341 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2342 if (sig_y > 9999999999999999ull) { | |
2343 non_canon_y = 1; | |
2344 } else { | |
2345 non_canon_y = 0; | |
2346 } | |
2347 } else { | |
2348 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
2349 sig_y = (y & MASK_BINARY_SIG1); | |
2350 non_canon_y = 0; | |
2351 } | |
2352 | |
2353 // ZERO (CASE4) | |
2354 // some properties: | |
2355 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
2356 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
2357 // therefore ignore the exponent field | |
2358 // (Any non-canonical # is considered 0) | |
2359 if (non_canon_x || sig_x == 0) { | |
2360 x_is_zero = 1; | |
2361 } | |
2362 if (non_canon_y || sig_y == 0) { | |
2363 y_is_zero = 1; | |
2364 } | |
2365 // if both numbers are zero, they are equal | |
2366 if (x_is_zero && y_is_zero) { | |
2367 res = 0; | |
2368 BID_RETURN (res); | |
2369 } | |
2370 // if x is zero, it is lessthan if Y is positive | |
2371 else if (x_is_zero) { | |
2372 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2373 BID_RETURN (res); | |
2374 } | |
2375 // if y is zero, X is less if it is negative | |
2376 else if (y_is_zero) { | |
2377 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2378 BID_RETURN (res); | |
2379 } | |
2380 // OPPOSITE SIGN (CASE5) | |
2381 // now, if the sign bits differ, x is less than if y is positive | |
2382 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2383 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2384 BID_RETURN (res); | |
2385 } | |
2386 // REDUNDANT REPRESENTATIONS (CASE6) | |
2387 // if both components are either bigger or smaller | |
2388 if (sig_x > sig_y && exp_x >= exp_y) { | |
2389 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2390 BID_RETURN (res); | |
2391 } | |
2392 if (sig_x < sig_y && exp_x <= exp_y) { | |
2393 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2394 BID_RETURN (res); | |
2395 } | |
2396 // if exp_x is 15 greater than exp_y, no need for compensation | |
2397 if (exp_x - exp_y > 15) { | |
2398 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2399 BID_RETURN (res); | |
2400 } | |
2401 // difference cannot be greater than 10^15 | |
2402 | |
2403 // if exp_x is 15 less than exp_y, no need for compensation | |
2404 if (exp_y - exp_x > 15) { | |
2405 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2406 BID_RETURN (res); | |
2407 } | |
2408 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2409 if (exp_x > exp_y) { // to simplify the loop below, | |
2410 | |
2411 // otherwise adjust the x significand upwards | |
2412 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2413 mult_factor[exp_x - exp_y]); | |
2414 | |
2415 // return 0 if values are equal | |
2416 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2417 res = 0; | |
2418 BID_RETURN (res); | |
2419 } | |
2420 // if postitive, return whichever significand abs is smaller | |
2421 // (converse if negative) | |
2422 { | |
2423 res = (((sig_n_prime.w[1] == 0) | |
2424 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
2425 MASK_SIGN)); | |
2426 BID_RETURN (res); | |
2427 } | |
2428 } | |
2429 // adjust the y significand upwards | |
2430 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2431 mult_factor[exp_y - exp_x]); | |
2432 | |
2433 // return 0 if values are equal | |
2434 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2435 res = 0; | |
2436 BID_RETURN (res); | |
2437 } | |
2438 // if positive, return whichever significand abs is smaller | |
2439 // (converse if negative) | |
2440 { | |
2441 res = (((sig_n_prime.w[1] > 0) | |
2442 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
2443 MASK_SIGN)); | |
2444 BID_RETURN (res); | |
2445 } | |
2446 } | |
2447 | |
2448 #if DECIMAL_CALL_BY_REFERENCE | |
2449 void | |
2450 bid64_signaling_less_equal (int *pres, UINT64 * px, | |
2451 UINT64 * | |
2452 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2453 _EXC_INFO_PARAM) { | |
2454 UINT64 x = *px; | |
2455 UINT64 y = *py; | |
2456 #else | |
2457 int | |
2458 bid64_signaling_less_equal (UINT64 x, | |
2459 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2460 _EXC_INFO_PARAM) { | |
2461 #endif | |
2462 int res; | |
2463 int exp_x, exp_y; | |
2464 UINT64 sig_x, sig_y; | |
2465 UINT128 sig_n_prime; | |
2466 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
2467 | |
2468 // NaN (CASE1) | |
2469 // if either number is NAN, the comparison is unordered, | |
2470 // rather than equal : return 0 | |
2471 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
2472 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
2473 res = 0; | |
2474 BID_RETURN (res); | |
2475 } | |
2476 // SIMPLE (CASE2) | |
2477 // if all the bits are the same, these numbers are equal (LESSEQUAL). | |
2478 if (x == y) { | |
2479 res = 1; | |
2480 BID_RETURN (res); | |
2481 } | |
2482 // INFINITY (CASE3) | |
2483 if ((x & MASK_INF) == MASK_INF) { | |
2484 // if x is neg infinity, it must be lessthan or equal to y return 1 | |
2485 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
2486 res = 1; | |
2487 BID_RETURN (res); | |
2488 } | |
2489 // x is pos infinity, it is greater, | |
2490 // unless y is positive infinity => return y==pos_infinity | |
2491 else { | |
2492 res = !(((y & MASK_INF) != MASK_INF) | |
2493 || ((y & MASK_SIGN) == MASK_SIGN)); | |
2494 BID_RETURN (res); | |
2495 } | |
2496 } else if ((y & MASK_INF) == MASK_INF) { | |
2497 // x is finite, so if y is positive infinity, then x is less, return 1 | |
2498 // if y is negative infinity, then x is greater, return 0 | |
2499 { | |
2500 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2501 BID_RETURN (res); | |
2502 } | |
2503 } | |
2504 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2505 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2506 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
2507 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2508 if (sig_x > 9999999999999999ull) { | |
2509 non_canon_x = 1; | |
2510 } else { | |
2511 non_canon_x = 0; | |
2512 } | |
2513 } else { | |
2514 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
2515 sig_x = (x & MASK_BINARY_SIG1); | |
2516 non_canon_x = 0; | |
2517 } | |
2518 | |
2519 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2520 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2521 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
2522 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2523 if (sig_y > 9999999999999999ull) { | |
2524 non_canon_y = 1; | |
2525 } else { | |
2526 non_canon_y = 0; | |
2527 } | |
2528 } else { | |
2529 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
2530 sig_y = (y & MASK_BINARY_SIG1); | |
2531 non_canon_y = 0; | |
2532 } | |
2533 | |
2534 // ZERO (CASE4) | |
2535 // some properties: | |
2536 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
2537 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
2538 // therefore ignore the exponent field | |
2539 // (Any non-canonical # is considered 0) | |
2540 if (non_canon_x || sig_x == 0) { | |
2541 x_is_zero = 1; | |
2542 } | |
2543 if (non_canon_y || sig_y == 0) { | |
2544 y_is_zero = 1; | |
2545 } | |
2546 // if both numbers are zero, they are equal -> return 1 | |
2547 if (x_is_zero && y_is_zero) { | |
2548 res = 1; | |
2549 BID_RETURN (res); | |
2550 } | |
2551 // if x is zero, it is lessthan if Y is positive | |
2552 else if (x_is_zero) { | |
2553 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2554 BID_RETURN (res); | |
2555 } | |
2556 // if y is zero, X is less if it is negative | |
2557 else if (y_is_zero) { | |
2558 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2559 BID_RETURN (res); | |
2560 } | |
2561 // OPPOSITE SIGN (CASE5) | |
2562 // now, if the sign bits differ, x is less than if y is positive | |
2563 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2564 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2565 BID_RETURN (res); | |
2566 } | |
2567 // REDUNDANT REPRESENTATIONS (CASE6) | |
2568 // if both components are either bigger or smaller | |
2569 if (sig_x > sig_y && exp_x >= exp_y) { | |
2570 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2571 BID_RETURN (res); | |
2572 } | |
2573 if (sig_x < sig_y && exp_x <= exp_y) { | |
2574 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2575 BID_RETURN (res); | |
2576 } | |
2577 // if exp_x is 15 greater than exp_y, no need for compensation | |
2578 if (exp_x - exp_y > 15) { | |
2579 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2580 BID_RETURN (res); | |
2581 } | |
2582 // difference cannot be greater than 10^15 | |
2583 | |
2584 // if exp_x is 15 less than exp_y, no need for compensation | |
2585 if (exp_y - exp_x > 15) { | |
2586 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2587 BID_RETURN (res); | |
2588 } | |
2589 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2590 if (exp_x > exp_y) { // to simplify the loop below, | |
2591 | |
2592 // otherwise adjust the x significand upwards | |
2593 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2594 mult_factor[exp_x - exp_y]); | |
2595 | |
2596 // return 1 if values are equal | |
2597 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2598 res = 1; | |
2599 BID_RETURN (res); | |
2600 } | |
2601 // if postitive, return whichever significand abs is smaller | |
2602 // (converse if negative) | |
2603 { | |
2604 res = (((sig_n_prime.w[1] == 0) | |
2605 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
2606 MASK_SIGN)); | |
2607 BID_RETURN (res); | |
2608 } | |
2609 } | |
2610 // adjust the y significand upwards | |
2611 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2612 mult_factor[exp_y - exp_x]); | |
2613 | |
2614 // return 1 if values are equal | |
2615 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2616 res = 1; | |
2617 BID_RETURN (res); | |
2618 } | |
2619 // if positive, return whichever significand abs is smaller | |
2620 // (converse if negative) | |
2621 { | |
2622 res = (((sig_n_prime.w[1] > 0) | |
2623 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
2624 MASK_SIGN)); | |
2625 BID_RETURN (res); | |
2626 } | |
2627 } | |
2628 | |
2629 #if DECIMAL_CALL_BY_REFERENCE | |
2630 void | |
2631 bid64_signaling_less_unordered (int *pres, UINT64 * px, | |
2632 UINT64 * | |
2633 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2634 _EXC_INFO_PARAM) { | |
2635 UINT64 x = *px; | |
2636 UINT64 y = *py; | |
2637 #else | |
2638 int | |
2639 bid64_signaling_less_unordered (UINT64 x, | |
2640 UINT64 y _EXC_FLAGS_PARAM | |
2641 _EXC_MASKS_PARAM _EXC_INFO_PARAM) { | |
2642 #endif | |
2643 int res; | |
2644 int exp_x, exp_y; | |
2645 UINT64 sig_x, sig_y; | |
2646 UINT128 sig_n_prime; | |
2647 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
2648 | |
2649 // NaN (CASE1) | |
2650 // if either number is NAN, the comparison is unordered : return 0 | |
2651 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
2652 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
2653 res = 1; | |
2654 BID_RETURN (res); | |
2655 } | |
2656 // SIMPLE (CASE2) | |
2657 // if all the bits are the same, these numbers are equal. | |
2658 if (x == y) { | |
2659 res = 0; | |
2660 BID_RETURN (res); | |
2661 } | |
2662 // INFINITY (CASE3) | |
2663 if ((x & MASK_INF) == MASK_INF) { | |
2664 // if x==neg_inf, { res = (y == neg_inf)?0:1; BID_RETURN (res) } | |
2665 if ((x & MASK_SIGN) == MASK_SIGN) | |
2666 // x is -inf, so it is less than y unless y is -inf | |
2667 { | |
2668 res = (((y & MASK_INF) != MASK_INF) | |
2669 || (y & MASK_SIGN) != MASK_SIGN); | |
2670 BID_RETURN (res); | |
2671 } else | |
2672 // x is pos_inf, no way for it to be less than y | |
2673 { | |
2674 res = 0; | |
2675 BID_RETURN (res); | |
2676 } | |
2677 } else if ((y & MASK_INF) == MASK_INF) { | |
2678 // x is finite, so: | |
2679 // if y is +inf, x<y | |
2680 // if y is -inf, x>y | |
2681 { | |
2682 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2683 BID_RETURN (res); | |
2684 } | |
2685 } | |
2686 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2687 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2688 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
2689 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2690 if (sig_x > 9999999999999999ull) { | |
2691 non_canon_x = 1; | |
2692 } else { | |
2693 non_canon_x = 0; | |
2694 } | |
2695 } else { | |
2696 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
2697 sig_x = (x & MASK_BINARY_SIG1); | |
2698 non_canon_x = 0; | |
2699 } | |
2700 | |
2701 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2702 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2703 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
2704 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2705 if (sig_y > 9999999999999999ull) { | |
2706 non_canon_y = 1; | |
2707 } else { | |
2708 non_canon_y = 0; | |
2709 } | |
2710 } else { | |
2711 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
2712 sig_y = (y & MASK_BINARY_SIG1); | |
2713 non_canon_y = 0; | |
2714 } | |
2715 | |
2716 // ZERO (CASE4) | |
2717 // some properties: | |
2718 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
2719 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
2720 // therefore ignore the exponent field | |
2721 // (Any non-canonical # is considered 0) | |
2722 if (non_canon_x || sig_x == 0) { | |
2723 x_is_zero = 1; | |
2724 } | |
2725 if (non_canon_y || sig_y == 0) { | |
2726 y_is_zero = 1; | |
2727 } | |
2728 // if both numbers are zero, they are equal | |
2729 if (x_is_zero && y_is_zero) { | |
2730 res = 0; | |
2731 BID_RETURN (res); | |
2732 } | |
2733 // if x is zero, it is lessthan if Y is positive | |
2734 else if (x_is_zero) { | |
2735 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2736 BID_RETURN (res); | |
2737 } | |
2738 // if y is zero, X is less if it is negative | |
2739 else if (y_is_zero) { | |
2740 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2741 BID_RETURN (res); | |
2742 } | |
2743 // OPPOSITE SIGN (CASE5) | |
2744 // now, if the sign bits differ, x is less than if y is positive | |
2745 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2746 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2747 BID_RETURN (res); | |
2748 } | |
2749 // REDUNDANT REPRESENTATIONS (CASE6) | |
2750 // if both components are either bigger or smaller | |
2751 if (sig_x > sig_y && exp_x >= exp_y) { | |
2752 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2753 BID_RETURN (res); | |
2754 } | |
2755 if (sig_x < sig_y && exp_x <= exp_y) { | |
2756 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2757 BID_RETURN (res); | |
2758 } | |
2759 // if exp_x is 15 greater than exp_y, no need for compensation | |
2760 if (exp_x - exp_y > 15) { | |
2761 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2762 BID_RETURN (res); | |
2763 } | |
2764 // difference cannot be greater than 10^15 | |
2765 | |
2766 // if exp_x is 15 less than exp_y, no need for compensation | |
2767 if (exp_y - exp_x > 15) { | |
2768 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2769 BID_RETURN (res); | |
2770 } | |
2771 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2772 if (exp_x > exp_y) { // to simplify the loop below, | |
2773 | |
2774 // otherwise adjust the x significand upwards | |
2775 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2776 mult_factor[exp_x - exp_y]); | |
2777 | |
2778 // return 0 if values are equal | |
2779 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2780 res = 0; | |
2781 BID_RETURN (res); | |
2782 } | |
2783 // if postitive, return whichever significand abs is smaller | |
2784 // (converse if negative) | |
2785 { | |
2786 res = (((sig_n_prime.w[1] == 0) | |
2787 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
2788 MASK_SIGN)); | |
2789 BID_RETURN (res); | |
2790 } | |
2791 } | |
2792 // adjust the y significand upwards | |
2793 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2794 mult_factor[exp_y - exp_x]); | |
2795 | |
2796 // return 0 if values are equal | |
2797 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2798 res = 0; | |
2799 BID_RETURN (res); | |
2800 } | |
2801 // if positive, return whichever significand abs is smaller | |
2802 // (converse if negative) | |
2803 { | |
2804 res = (((sig_n_prime.w[1] > 0) | |
2805 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
2806 MASK_SIGN)); | |
2807 BID_RETURN (res); | |
2808 } | |
2809 } | |
2810 | |
2811 #if DECIMAL_CALL_BY_REFERENCE | |
2812 void | |
2813 bid64_signaling_not_greater (int *pres, UINT64 * px, | |
2814 UINT64 * | |
2815 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2816 _EXC_INFO_PARAM) { | |
2817 UINT64 x = *px; | |
2818 UINT64 y = *py; | |
2819 #else | |
2820 int | |
2821 bid64_signaling_not_greater (UINT64 x, | |
2822 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2823 _EXC_INFO_PARAM) { | |
2824 #endif | |
2825 int res; | |
2826 int exp_x, exp_y; | |
2827 UINT64 sig_x, sig_y; | |
2828 UINT128 sig_n_prime; | |
2829 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
2830 | |
2831 // NaN (CASE1) | |
2832 // if either number is NAN, the comparison is unordered, | |
2833 // rather than equal : return 0 | |
2834 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
2835 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
2836 res = 1; | |
2837 BID_RETURN (res); | |
2838 } | |
2839 // SIMPLE (CASE2) | |
2840 // if all the bits are the same, these numbers are equal (LESSEQUAL). | |
2841 if (x == y) { | |
2842 res = 1; | |
2843 BID_RETURN (res); | |
2844 } | |
2845 // INFINITY (CASE3) | |
2846 if ((x & MASK_INF) == MASK_INF) { | |
2847 // if x is neg infinity, it must be lessthan or equal to y return 1 | |
2848 if (((x & MASK_SIGN) == MASK_SIGN)) { | |
2849 res = 1; | |
2850 BID_RETURN (res); | |
2851 } | |
2852 // x is pos infinity, it is greater, | |
2853 // unless y is positive infinity => return y==pos_infinity | |
2854 else { | |
2855 res = !(((y & MASK_INF) != MASK_INF) | |
2856 || ((y & MASK_SIGN) == MASK_SIGN)); | |
2857 BID_RETURN (res); | |
2858 } | |
2859 } else if ((y & MASK_INF) == MASK_INF) { | |
2860 // x is finite, so if y is positive infinity, then x is less, return 1 | |
2861 // if y is negative infinity, then x is greater, return 0 | |
2862 { | |
2863 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2864 BID_RETURN (res); | |
2865 } | |
2866 } | |
2867 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2868 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2869 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
2870 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2871 if (sig_x > 9999999999999999ull) { | |
2872 non_canon_x = 1; | |
2873 } else { | |
2874 non_canon_x = 0; | |
2875 } | |
2876 } else { | |
2877 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
2878 sig_x = (x & MASK_BINARY_SIG1); | |
2879 non_canon_x = 0; | |
2880 } | |
2881 | |
2882 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
2883 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
2884 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
2885 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
2886 if (sig_y > 9999999999999999ull) { | |
2887 non_canon_y = 1; | |
2888 } else { | |
2889 non_canon_y = 0; | |
2890 } | |
2891 } else { | |
2892 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
2893 sig_y = (y & MASK_BINARY_SIG1); | |
2894 non_canon_y = 0; | |
2895 } | |
2896 | |
2897 // ZERO (CASE4) | |
2898 // some properties: | |
2899 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
2900 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
2901 // therefore ignore the exponent field | |
2902 // (Any non-canonical # is considered 0) | |
2903 if (non_canon_x || sig_x == 0) { | |
2904 x_is_zero = 1; | |
2905 } | |
2906 if (non_canon_y || sig_y == 0) { | |
2907 y_is_zero = 1; | |
2908 } | |
2909 // if both numbers are zero, they are equal -> return 1 | |
2910 if (x_is_zero && y_is_zero) { | |
2911 res = 1; | |
2912 BID_RETURN (res); | |
2913 } | |
2914 // if x is zero, it is lessthan if Y is positive | |
2915 else if (x_is_zero) { | |
2916 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2917 BID_RETURN (res); | |
2918 } | |
2919 // if y is zero, X is less if it is negative | |
2920 else if (y_is_zero) { | |
2921 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2922 BID_RETURN (res); | |
2923 } | |
2924 // OPPOSITE SIGN (CASE5) | |
2925 // now, if the sign bits differ, x is less than if y is positive | |
2926 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
2927 res = ((y & MASK_SIGN) != MASK_SIGN); | |
2928 BID_RETURN (res); | |
2929 } | |
2930 // REDUNDANT REPRESENTATIONS (CASE6) | |
2931 // if both components are either bigger or smaller | |
2932 if (sig_x > sig_y && exp_x >= exp_y) { | |
2933 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2934 BID_RETURN (res); | |
2935 } | |
2936 if (sig_x < sig_y && exp_x <= exp_y) { | |
2937 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2938 BID_RETURN (res); | |
2939 } | |
2940 // if exp_x is 15 greater than exp_y, no need for compensation | |
2941 if (exp_x - exp_y > 15) { | |
2942 res = ((x & MASK_SIGN) == MASK_SIGN); | |
2943 BID_RETURN (res); | |
2944 } | |
2945 // difference cannot be greater than 10^15 | |
2946 | |
2947 // if exp_x is 15 less than exp_y, no need for compensation | |
2948 if (exp_y - exp_x > 15) { | |
2949 res = ((x & MASK_SIGN) != MASK_SIGN); | |
2950 BID_RETURN (res); | |
2951 } | |
2952 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
2953 if (exp_x > exp_y) { // to simplify the loop below, | |
2954 | |
2955 // otherwise adjust the x significand upwards | |
2956 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
2957 mult_factor[exp_x - exp_y]); | |
2958 | |
2959 // return 1 if values are equal | |
2960 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
2961 res = 1; | |
2962 BID_RETURN (res); | |
2963 } | |
2964 // if postitive, return whichever significand abs is smaller | |
2965 // (converse if negative) | |
2966 { | |
2967 res = (((sig_n_prime.w[1] == 0) | |
2968 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == | |
2969 MASK_SIGN)); | |
2970 BID_RETURN (res); | |
2971 } | |
2972 } | |
2973 // adjust the y significand upwards | |
2974 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
2975 mult_factor[exp_y - exp_x]); | |
2976 | |
2977 // return 1 if values are equal | |
2978 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
2979 res = 1; | |
2980 BID_RETURN (res); | |
2981 } | |
2982 // if positive, return whichever significand abs is smaller | |
2983 // (converse if negative) | |
2984 { | |
2985 res = (((sig_n_prime.w[1] > 0) | |
2986 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == | |
2987 MASK_SIGN)); | |
2988 BID_RETURN (res); | |
2989 } | |
2990 } | |
2991 | |
2992 #if DECIMAL_CALL_BY_REFERENCE | |
2993 void | |
2994 bid64_signaling_not_less (int *pres, UINT64 * px, | |
2995 UINT64 * | |
2996 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
2997 _EXC_INFO_PARAM) { | |
2998 UINT64 x = *px; | |
2999 UINT64 y = *py; | |
3000 #else | |
3001 int | |
3002 bid64_signaling_not_less (UINT64 x, | |
3003 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM | |
3004 _EXC_INFO_PARAM) { | |
3005 #endif | |
3006 int res; | |
3007 int exp_x, exp_y; | |
3008 UINT64 sig_x, sig_y; | |
3009 UINT128 sig_n_prime; | |
3010 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; | |
3011 | |
3012 // NaN (CASE1) | |
3013 // if either number is NAN, the comparison is unordered : return 1 | |
3014 if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) { | |
3015 *pfpsf |= INVALID_EXCEPTION; // set invalid exception if NaN | |
3016 res = 1; | |
3017 BID_RETURN (res); | |
3018 } | |
3019 // SIMPLE (CASE2) | |
3020 // if all the bits are the same, these numbers are equal. | |
3021 if (x == y) { | |
3022 res = 1; | |
3023 BID_RETURN (res); | |
3024 } | |
3025 // INFINITY (CASE3) | |
3026 if ((x & MASK_INF) == MASK_INF) { | |
3027 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } | |
3028 if ((x & MASK_SIGN) == MASK_SIGN) | |
3029 // x is -inf, so it is less than y unless y is -inf | |
3030 { | |
3031 res = (((y & MASK_INF) == MASK_INF) | |
3032 && (y & MASK_SIGN) == MASK_SIGN); | |
3033 BID_RETURN (res); | |
3034 } else | |
3035 // x is pos_inf, no way for it to be less than y | |
3036 { | |
3037 res = 1; | |
3038 BID_RETURN (res); | |
3039 } | |
3040 } else if ((y & MASK_INF) == MASK_INF) { | |
3041 // x is finite, so: | |
3042 // if y is +inf, x<y | |
3043 // if y is -inf, x>y | |
3044 { | |
3045 res = ((y & MASK_SIGN) == MASK_SIGN); | |
3046 BID_RETURN (res); | |
3047 } | |
3048 } | |
3049 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
3050 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
3051 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; | |
3052 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
3053 if (sig_x > 9999999999999999ull) { | |
3054 non_canon_x = 1; | |
3055 } else { | |
3056 non_canon_x = 0; | |
3057 } | |
3058 } else { | |
3059 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; | |
3060 sig_x = (x & MASK_BINARY_SIG1); | |
3061 non_canon_x = 0; | |
3062 } | |
3063 | |
3064 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => | |
3065 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { | |
3066 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; | |
3067 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; | |
3068 if (sig_y > 9999999999999999ull) { | |
3069 non_canon_y = 1; | |
3070 } else { | |
3071 non_canon_y = 0; | |
3072 } | |
3073 } else { | |
3074 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; | |
3075 sig_y = (y & MASK_BINARY_SIG1); | |
3076 non_canon_y = 0; | |
3077 } | |
3078 | |
3079 // ZERO (CASE4) | |
3080 // some properties: | |
3081 // (+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater | |
3082 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => | |
3083 // therefore ignore the exponent field | |
3084 // (Any non-canonical # is considered 0) | |
3085 if (non_canon_x || sig_x == 0) { | |
3086 x_is_zero = 1; | |
3087 } | |
3088 if (non_canon_y || sig_y == 0) { | |
3089 y_is_zero = 1; | |
3090 } | |
3091 // if both numbers are zero, they are equal | |
3092 if (x_is_zero && y_is_zero) { | |
3093 res = 1; | |
3094 BID_RETURN (res); | |
3095 } | |
3096 // if x is zero, it is lessthan if Y is positive | |
3097 else if (x_is_zero) { | |
3098 res = ((y & MASK_SIGN) == MASK_SIGN); | |
3099 BID_RETURN (res); | |
3100 } | |
3101 // if y is zero, X is less if it is negative | |
3102 else if (y_is_zero) { | |
3103 res = ((x & MASK_SIGN) != MASK_SIGN); | |
3104 BID_RETURN (res); | |
3105 } | |
3106 // OPPOSITE SIGN (CASE5) | |
3107 // now, if the sign bits differ, x is less than if y is positive | |
3108 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) { | |
3109 res = ((y & MASK_SIGN) == MASK_SIGN); | |
3110 BID_RETURN (res); | |
3111 } | |
3112 // REDUNDANT REPRESENTATIONS (CASE6) | |
3113 // if both components are either bigger or smaller | |
3114 if (sig_x > sig_y && exp_x >= exp_y) { | |
3115 res = ((x & MASK_SIGN) != MASK_SIGN); | |
3116 BID_RETURN (res); | |
3117 } | |
3118 if (sig_x < sig_y && exp_x <= exp_y) { | |
3119 res = ((x & MASK_SIGN) == MASK_SIGN); | |
3120 BID_RETURN (res); | |
3121 } | |
3122 // if exp_x is 15 greater than exp_y, no need for compensation | |
3123 if (exp_x - exp_y > 15) { | |
3124 res = ((x & MASK_SIGN) != MASK_SIGN); | |
3125 BID_RETURN (res); | |
3126 } | |
3127 // difference cannot be greater than 10^15 | |
3128 | |
3129 // if exp_x is 15 less than exp_y, no need for compensation | |
3130 if (exp_y - exp_x > 15) { | |
3131 res = ((x & MASK_SIGN) == MASK_SIGN); | |
3132 BID_RETURN (res); | |
3133 } | |
3134 // if |exp_x - exp_y| < 15, it comes down to the compensated significand | |
3135 if (exp_x > exp_y) { // to simplify the loop below, | |
3136 | |
3137 // otherwise adjust the x significand upwards | |
3138 __mul_64x64_to_128MACH (sig_n_prime, sig_x, | |
3139 mult_factor[exp_x - exp_y]); | |
3140 | |
3141 // return 0 if values are equal | |
3142 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { | |
3143 res = 1; | |
3144 BID_RETURN (res); | |
3145 } | |
3146 // if postitive, return whichever significand abs is smaller | |
3147 // (converse if negative) | |
3148 { | |
3149 res = (((sig_n_prime.w[1] == 0) | |
3150 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) != | |
3151 MASK_SIGN)); | |
3152 BID_RETURN (res); | |
3153 } | |
3154 } | |
3155 // adjust the y significand upwards | |
3156 __mul_64x64_to_128MACH (sig_n_prime, sig_y, | |
3157 mult_factor[exp_y - exp_x]); | |
3158 | |
3159 // return 0 if values are equal | |
3160 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { | |
3161 res = 1; | |
3162 BID_RETURN (res); | |
3163 } | |
3164 // if positive, return whichever significand abs is smaller | |
3165 // (converse if negative) | |
3166 { | |
3167 res = (((sig_n_prime.w[1] > 0) | |
3168 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) != | |
3169 MASK_SIGN)); | |
3170 BID_RETURN (res); | |
3171 } | |
3172 } |