OSDN Git Service

* trans-decl.c (gfc_build_qualified_array): Don't skip generation
[pf3gnuchains/gcc-fork.git] / libgcc / config / libbid / bid64_round_integral.c
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 /*****************************************************************************
27  *  BID64_round_integral_exact
28  ****************************************************************************/
29
30 #if DECIMAL_CALL_BY_REFERENCE
31 void
32 bid64_round_integral_exact (UINT64 * pres,
33                             UINT64 *
34                             px _RND_MODE_PARAM _EXC_FLAGS_PARAM
35                             _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
36   UINT64 x = *px;
37 #if !DECIMAL_GLOBAL_ROUNDING
38   unsigned int rnd_mode = *prnd_mode;
39 #endif
40 #else
41 UINT64
42 bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM
43                             _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
44 #endif
45
46   UINT64 res = 0xbaddbaddbaddbaddull;
47   UINT64 x_sign;
48   int exp;                      // unbiased exponent
49   // Note: C1 represents the significand (UINT64)
50   BID_UI64DOUBLE tmp1;
51   int x_nr_bits;
52   int q, ind, shift;
53   UINT64 C1;
54   // UINT64 res is C* at first - represents up to 16 decimal digits <= 54 bits
55   UINT128 fstar = { {0x0ull, 0x0ull} };
56   UINT128 P128;
57
58   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
59
60   // check for NaNs and infinities
61   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
62     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
63       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
64     else
65       x = x & 0xfe03ffffffffffffull;    // clear G6-G12
66     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
67       // set invalid flag
68       *pfpsf |= INVALID_EXCEPTION;
69       // return quiet (SNaN)
70       res = x & 0xfdffffffffffffffull;
71     } else {    // QNaN
72       res = x;
73     }
74     BID_RETURN (res);
75   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
76     res = x_sign | 0x7800000000000000ull;
77     BID_RETURN (res);
78   }
79   // unpack x
80   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
81     // if the steering bits are 11 (condition will be 0), then 
82     // the exponent is G[0:w+1]
83     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
84     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
85     if (C1 > 9999999999999999ull) {     // non-canonical
86       C1 = 0;
87     }
88   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
89     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
90     C1 = (x & MASK_BINARY_SIG1);
91   }
92
93   // if x is 0 or non-canonical return 0 preserving the sign bit and 
94   // the preferred exponent of MAX(Q(x), 0)
95   if (C1 == 0) {
96     if (exp < 0)
97       exp = 0;
98     res = x_sign | (((UINT64) exp + 398) << 53);
99     BID_RETURN (res);
100   }
101   // x is a finite non-zero number (not 0, non-canonical, or special)
102
103   switch (rnd_mode) {
104   case ROUNDING_TO_NEAREST:
105   case ROUNDING_TIES_AWAY:
106     // return 0 if (exp <= -(p+1))
107     if (exp <= -17) {
108       res = x_sign | 0x31c0000000000000ull;
109       *pfpsf |= INEXACT_EXCEPTION;
110       BID_RETURN (res);
111     }
112     break;
113   case ROUNDING_DOWN:
114     // return 0 if (exp <= -p)
115     if (exp <= -16) {
116       if (x_sign) {
117         res = 0xb1c0000000000001ull;
118       } else {
119         res = 0x31c0000000000000ull;
120       }
121       *pfpsf |= INEXACT_EXCEPTION;
122       BID_RETURN (res);
123     }
124     break;
125   case ROUNDING_UP:
126     // return 0 if (exp <= -p)
127     if (exp <= -16) {
128       if (x_sign) {
129         res = 0xb1c0000000000000ull;
130       } else {
131         res = 0x31c0000000000001ull;
132       }
133       *pfpsf |= INEXACT_EXCEPTION;
134       BID_RETURN (res);
135     }
136     break;
137   case ROUNDING_TO_ZERO:
138     // return 0 if (exp <= -p) 
139     if (exp <= -16) {
140       res = x_sign | 0x31c0000000000000ull;
141       *pfpsf |= INEXACT_EXCEPTION;
142       BID_RETURN (res);
143     }
144     break;
145   }     // end switch ()
146
147   // q = nr. of decimal digits in x (1 <= q <= 54)
148   //  determine first the nr. of bits in x
149   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
150     q = 16;
151   } else {      // if x < 2^53
152     tmp1.d = (double) C1;       // exact conversion
153     x_nr_bits =
154       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
155     q = nr_digits[x_nr_bits - 1].digits;
156     if (q == 0) {
157       q = nr_digits[x_nr_bits - 1].digits1;
158       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
159         q++;
160     }
161   }
162
163   if (exp >= 0) {       // -exp <= 0
164     // the argument is an integer already
165     res = x;
166     BID_RETURN (res);
167   }
168
169   switch (rnd_mode) {
170   case ROUNDING_TO_NEAREST:
171     if ((q + exp) >= 0) {       // exp < 0 and 1 <= -exp <= q
172       // need to shift right -exp digits from the coefficient; exp will be 0
173       ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
174       // chop off ind digits from the lower part of C1 
175       // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
176       // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
177       C1 = C1 + midpoint64[ind - 1];
178       // calculate C* and f*
179       // C* is actually floor(C*) in this case
180       // C* and f* need shifting and masking, as shown by
181       // shiftright128[] and maskhigh128[]
182       // 1 <= x <= 16
183       // kx = 10^(-x) = ten2mk64[ind - 1]
184       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
185       // the approximation of 10^(-x) was rounded up to 64 bits
186       __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
187
188       // if (0 < f* < 10^(-x)) then the result is a midpoint
189       //   if floor(C*) is even then C* = floor(C*) - logical right
190       //       shift; C* has p decimal digits, correct by Prop. 1)
191       //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
192       //       shift; C* has p decimal digits, correct by Pr. 1)
193       // else  
194       //   C* = floor(C*) (logical right shift; C has p decimal digits,
195       //       correct by Property 1)
196       // n = C* * 10^(e+x)  
197
198       if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
199         res = P128.w[1];
200         fstar.w[1] = 0;
201         fstar.w[0] = P128.w[0];
202       } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
203         shift = shiftright128[ind - 1]; // 3 <= shift <= 63
204         res = (P128.w[1] >> shift);
205         fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
206         fstar.w[0] = P128.w[0];
207       }
208       // if (0 < f* < 10^(-x)) then the result is a midpoint
209       // since round_to_even, subtract 1 if current result is odd
210       if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
211           && (fstar.w[0] < ten2mk64[ind - 1])) {
212         res--;
213       }
214       // determine inexactness of the rounding of C*
215       // if (0 < f* - 1/2 < 10^(-x)) then
216       //   the result is exact
217       // else // if (f* - 1/2 > T*) then
218       //   the result is inexact
219       if (ind - 1 <= 2) {
220         if (fstar.w[0] > 0x8000000000000000ull) {
221           // f* > 1/2 and the result may be exact
222           // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
223           if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
224             // set the inexact flag
225             *pfpsf |= INEXACT_EXCEPTION;
226           }     // else the result is exact
227         } else {        // the result is inexact; f2* <= 1/2
228           // set the inexact flag
229           *pfpsf |= INEXACT_EXCEPTION;
230         }
231       } else {  // if 3 <= ind - 1 <= 21
232         if (fstar.w[1] > onehalf128[ind - 1] ||
233             (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
234           // f2* > 1/2 and the result may be exact
235           // Calculate f2* - 1/2
236           if (fstar.w[1] > onehalf128[ind - 1]
237               || fstar.w[0] > ten2mk64[ind - 1]) {
238             // set the inexact flag
239             *pfpsf |= INEXACT_EXCEPTION;
240           }     // else the result is exact
241         } else {        // the result is inexact; f2* <= 1/2
242           // set the inexact flag
243           *pfpsf |= INEXACT_EXCEPTION;
244         }
245       }
246       // set exponent to zero as it was negative before.
247       res = x_sign | 0x31c0000000000000ull | res;
248       BID_RETURN (res);
249     } else {    // if exp < 0 and q + exp < 0
250       // the result is +0 or -0
251       res = x_sign | 0x31c0000000000000ull;
252       *pfpsf |= INEXACT_EXCEPTION;
253       BID_RETURN (res);
254     }
255     break;
256   case ROUNDING_TIES_AWAY:
257     if ((q + exp) >= 0) {       // exp < 0 and 1 <= -exp <= q
258       // need to shift right -exp digits from the coefficient; exp will be 0
259       ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
260       // chop off ind digits from the lower part of C1 
261       // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
262       // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
263       C1 = C1 + midpoint64[ind - 1];
264       // calculate C* and f*
265       // C* is actually floor(C*) in this case
266       // C* and f* need shifting and masking, as shown by
267       // shiftright128[] and maskhigh128[]
268       // 1 <= x <= 16
269       // kx = 10^(-x) = ten2mk64[ind - 1]
270       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
271       // the approximation of 10^(-x) was rounded up to 64 bits
272       __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
273
274       // if (0 < f* < 10^(-x)) then the result is a midpoint
275       //   C* = floor(C*) - logical right shift; C* has p decimal digits, 
276       //       correct by Prop. 1)
277       // else
278       //   C* = floor(C*) (logical right shift; C has p decimal digits,
279       //       correct by Property 1)
280       // n = C* * 10^(e+x)
281
282       if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
283         res = P128.w[1];
284         fstar.w[1] = 0;
285         fstar.w[0] = P128.w[0];
286       } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
287         shift = shiftright128[ind - 1]; // 3 <= shift <= 63
288         res = (P128.w[1] >> shift);
289         fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
290         fstar.w[0] = P128.w[0];
291       }
292       // midpoints are already rounded correctly
293       // determine inexactness of the rounding of C*
294       // if (0 < f* - 1/2 < 10^(-x)) then
295       //   the result is exact
296       // else // if (f* - 1/2 > T*) then
297       //   the result is inexact
298       if (ind - 1 <= 2) {
299         if (fstar.w[0] > 0x8000000000000000ull) {
300           // f* > 1/2 and the result may be exact 
301           // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
302           if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
303             // set the inexact flag
304             *pfpsf |= INEXACT_EXCEPTION;
305           }     // else the result is exact
306         } else {        // the result is inexact; f2* <= 1/2
307           // set the inexact flag
308           *pfpsf |= INEXACT_EXCEPTION;
309         }
310       } else {  // if 3 <= ind - 1 <= 21
311         if (fstar.w[1] > onehalf128[ind - 1] ||
312             (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
313           // f2* > 1/2 and the result may be exact
314           // Calculate f2* - 1/2
315           if (fstar.w[1] > onehalf128[ind - 1]
316               || fstar.w[0] > ten2mk64[ind - 1]) {
317             // set the inexact flag
318             *pfpsf |= INEXACT_EXCEPTION;
319           }     // else the result is exact
320         } else {        // the result is inexact; f2* <= 1/2
321           // set the inexact flag
322           *pfpsf |= INEXACT_EXCEPTION;
323         }
324       }
325       // set exponent to zero as it was negative before.
326       res = x_sign | 0x31c0000000000000ull | res;
327       BID_RETURN (res);
328     } else {    // if exp < 0 and q + exp < 0
329       // the result is +0 or -0
330       res = x_sign | 0x31c0000000000000ull;
331       *pfpsf |= INEXACT_EXCEPTION;
332       BID_RETURN (res);
333     }
334     break;
335   case ROUNDING_DOWN:
336     if ((q + exp) > 0) {        // exp < 0 and 1 <= -exp < q
337       // need to shift right -exp digits from the coefficient; exp will be 0
338       ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
339       // chop off ind digits from the lower part of C1 
340       // C1 fits in 64 bits
341       // calculate C* and f*
342       // C* is actually floor(C*) in this case
343       // C* and f* need shifting and masking, as shown by
344       // shiftright128[] and maskhigh128[]
345       // 1 <= x <= 16
346       // kx = 10^(-x) = ten2mk64[ind - 1]
347       // C* = C1 * 10^(-x)
348       // the approximation of 10^(-x) was rounded up to 64 bits
349       __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
350
351       // C* = floor(C*) (logical right shift; C has p decimal digits,
352       //       correct by Property 1)
353       // if (0 < f* < 10^(-x)) then the result is exact
354       // n = C* * 10^(e+x)  
355
356       if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
357         res = P128.w[1];
358         fstar.w[1] = 0;
359         fstar.w[0] = P128.w[0];
360       } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
361         shift = shiftright128[ind - 1]; // 3 <= shift <= 63
362         res = (P128.w[1] >> shift);
363         fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
364         fstar.w[0] = P128.w[0];
365       }
366       // if (f* > 10^(-x)) then the result is inexact
367       if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
368         if (x_sign) {
369           // if negative and not exact, increment magnitude
370           res++;
371         }
372         *pfpsf |= INEXACT_EXCEPTION;
373       }
374       // set exponent to zero as it was negative before.
375       res = x_sign | 0x31c0000000000000ull | res;
376       BID_RETURN (res);
377     } else {    // if exp < 0 and q + exp <= 0
378       // the result is +0 or -1
379       if (x_sign) {
380         res = 0xb1c0000000000001ull;
381       } else {
382         res = 0x31c0000000000000ull;
383       }
384       *pfpsf |= INEXACT_EXCEPTION;
385       BID_RETURN (res);
386     }
387     break;
388   case ROUNDING_UP:
389     if ((q + exp) > 0) {        // exp < 0 and 1 <= -exp < q
390       // need to shift right -exp digits from the coefficient; exp will be 0
391       ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
392       // chop off ind digits from the lower part of C1 
393       // C1 fits in 64 bits
394       // calculate C* and f*
395       // C* is actually floor(C*) in this case
396       // C* and f* need shifting and masking, as shown by
397       // shiftright128[] and maskhigh128[]
398       // 1 <= x <= 16
399       // kx = 10^(-x) = ten2mk64[ind - 1]
400       // C* = C1 * 10^(-x)
401       // the approximation of 10^(-x) was rounded up to 64 bits
402       __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
403
404       // C* = floor(C*) (logical right shift; C has p decimal digits,
405       //       correct by Property 1)
406       // if (0 < f* < 10^(-x)) then the result is exact
407       // n = C* * 10^(e+x)  
408
409       if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
410         res = P128.w[1];
411         fstar.w[1] = 0;
412         fstar.w[0] = P128.w[0];
413       } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
414         shift = shiftright128[ind - 1]; // 3 <= shift <= 63
415         res = (P128.w[1] >> shift);
416         fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
417         fstar.w[0] = P128.w[0];
418       }
419       // if (f* > 10^(-x)) then the result is inexact
420       if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
421         if (!x_sign) {
422           // if positive and not exact, increment magnitude
423           res++;
424         }
425         *pfpsf |= INEXACT_EXCEPTION;
426       }
427       // set exponent to zero as it was negative before.
428       res = x_sign | 0x31c0000000000000ull | res;
429       BID_RETURN (res);
430     } else {    // if exp < 0 and q + exp <= 0
431       // the result is -0 or +1
432       if (x_sign) {
433         res = 0xb1c0000000000000ull;
434       } else {
435         res = 0x31c0000000000001ull;
436       }
437       *pfpsf |= INEXACT_EXCEPTION;
438       BID_RETURN (res);
439     }
440     break;
441   case ROUNDING_TO_ZERO:
442     if ((q + exp) >= 0) {       // exp < 0 and 1 <= -exp <= q
443       // need to shift right -exp digits from the coefficient; exp will be 0
444       ind = -exp;       // 1 <= ind <= 16; ind is a synonym for 'x'
445       // chop off ind digits from the lower part of C1 
446       // C1 fits in 127 bits
447       // calculate C* and f*
448       // C* is actually floor(C*) in this case
449       // C* and f* need shifting and masking, as shown by
450       // shiftright128[] and maskhigh128[]
451       // 1 <= x <= 16
452       // kx = 10^(-x) = ten2mk64[ind - 1]
453       // C* = C1 * 10^(-x)
454       // the approximation of 10^(-x) was rounded up to 64 bits
455       __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
456
457       // C* = floor(C*) (logical right shift; C has p decimal digits,
458       //       correct by Property 1)
459       // if (0 < f* < 10^(-x)) then the result is exact
460       // n = C* * 10^(e+x)  
461
462       if (ind - 1 <= 2) {       // 0 <= ind - 1 <= 2 => shift = 0
463         res = P128.w[1];
464         fstar.w[1] = 0;
465         fstar.w[0] = P128.w[0];
466       } else if (ind - 1 <= 21) {       // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
467         shift = shiftright128[ind - 1]; // 3 <= shift <= 63
468         res = (P128.w[1] >> shift);
469         fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
470         fstar.w[0] = P128.w[0];
471       }
472       // if (f* > 10^(-x)) then the result is inexact
473       if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
474         *pfpsf |= INEXACT_EXCEPTION;
475       }
476       // set exponent to zero as it was negative before.
477       res = x_sign | 0x31c0000000000000ull | res;
478       BID_RETURN (res);
479     } else {    // if exp < 0 and q + exp < 0
480       // the result is +0 or -0
481       res = x_sign | 0x31c0000000000000ull;
482       *pfpsf |= INEXACT_EXCEPTION;
483       BID_RETURN (res);
484     }
485     break;
486   }     // end switch ()
487   BID_RETURN (res);
488 }
489
490 /*****************************************************************************
491  *  BID64_round_integral_nearest_even
492  ****************************************************************************/
493
494 #if DECIMAL_CALL_BY_REFERENCE
495 void
496 bid64_round_integral_nearest_even (UINT64 * pres,
497                                    UINT64 *
498                                    px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
499                                    _EXC_INFO_PARAM) {
500   UINT64 x = *px;
501 #else
502 UINT64
503 bid64_round_integral_nearest_even (UINT64 x _EXC_FLAGS_PARAM
504                                    _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
505 #endif
506
507   UINT64 res = 0xbaddbaddbaddbaddull;
508   UINT64 x_sign;
509   int exp;                      // unbiased exponent
510   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
511   BID_UI64DOUBLE tmp1;
512   int x_nr_bits;
513   int q, ind, shift;
514   UINT64 C1;
515   UINT128 fstar;
516   UINT128 P128;
517
518   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
519
520   // check for NaNs and infinities
521   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
522     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
523       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
524     else
525       x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
526     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
527       // set invalid flag 
528       *pfpsf |= INVALID_EXCEPTION;
529       // return quiet (SNaN) 
530       res = x & 0xfdffffffffffffffull;
531     } else {    // QNaN
532       res = x;
533     }
534     BID_RETURN (res);
535   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
536     res = x_sign | 0x7800000000000000ull;
537     BID_RETURN (res);
538   }
539   // unpack x
540   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
541     // if the steering bits are 11 (condition will be 0), then
542     // the exponent is G[0:w+1]
543     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
544     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
545     if (C1 > 9999999999999999ull) {     // non-canonical
546       C1 = 0;
547     }
548   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
549     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
550     C1 = (x & MASK_BINARY_SIG1);
551   }
552
553   // if x is 0 or non-canonical
554   if (C1 == 0) {
555     if (exp < 0)
556       exp = 0;
557     res = x_sign | (((UINT64) exp + 398) << 53);
558     BID_RETURN (res);
559   }
560   // x is a finite non-zero number (not 0, non-canonical, or special)
561
562   // return 0 if (exp <= -(p+1))
563   if (exp <= -17) {
564     res = x_sign | 0x31c0000000000000ull;
565     BID_RETURN (res);
566   }
567   // q = nr. of decimal digits in x (1 <= q <= 54)
568   //  determine first the nr. of bits in x
569   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
570     q = 16;
571   } else {      // if x < 2^53
572     tmp1.d = (double) C1;       // exact conversion
573     x_nr_bits =
574       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
575     q = nr_digits[x_nr_bits - 1].digits;
576     if (q == 0) {
577       q = nr_digits[x_nr_bits - 1].digits1;
578       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
579         q++;
580     }
581   }
582
583   if (exp >= 0) {       // -exp <= 0
584     // the argument is an integer already
585     res = x;
586     BID_RETURN (res);
587   } else if ((q + exp) >= 0) {  // exp < 0 and 1 <= -exp <= q
588     // need to shift right -exp digits from the coefficient; the exp will be 0
589     ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
590     // chop off ind digits from the lower part of C1 
591     // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
592     // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
593     C1 = C1 + midpoint64[ind - 1];
594     // calculate C* and f*
595     // C* is actually floor(C*) in this case
596     // C* and f* need shifting and masking, as shown by
597     // shiftright128[] and maskhigh128[]
598     // 1 <= x <= 16
599     // kx = 10^(-x) = ten2mk64[ind - 1]
600     // C* = (C1 + 1/2 * 10^x) * 10^(-x)
601     // the approximation of 10^(-x) was rounded up to 64 bits
602     __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
603
604     // if (0 < f* < 10^(-x)) then the result is a midpoint
605     //   if floor(C*) is even then C* = floor(C*) - logical right
606     //       shift; C* has p decimal digits, correct by Prop. 1)
607     //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
608     //       shift; C* has p decimal digits, correct by Pr. 1)
609     // else  
610     //   C* = floor(C*) (logical right shift; C has p decimal digits,
611     //       correct by Property 1)
612     // n = C* * 10^(e+x)  
613
614     if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
615       res = P128.w[1];
616       fstar.w[1] = 0;
617       fstar.w[0] = P128.w[0];
618     } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
619       shift = shiftright128[ind - 1];   // 3 <= shift <= 63
620       res = (P128.w[1] >> shift);
621       fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
622       fstar.w[0] = P128.w[0];
623     }
624     // if (0 < f* < 10^(-x)) then the result is a midpoint
625     // since round_to_even, subtract 1 if current result is odd
626     if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
627         && (fstar.w[0] < ten2mk64[ind - 1])) {
628       res--;
629     }
630     // set exponent to zero as it was negative before.
631     res = x_sign | 0x31c0000000000000ull | res;
632     BID_RETURN (res);
633   } else {      // if exp < 0 and q + exp < 0
634     // the result is +0 or -0
635     res = x_sign | 0x31c0000000000000ull;
636     BID_RETURN (res);
637   }
638 }
639
640 /*****************************************************************************
641  *  BID64_round_integral_negative
642  *****************************************************************************/
643
644 #if DECIMAL_CALL_BY_REFERENCE
645 void
646 bid64_round_integral_negative (UINT64 * pres,
647                                UINT64 *
648                                px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
649                                _EXC_INFO_PARAM) {
650   UINT64 x = *px;
651 #else
652 UINT64
653 bid64_round_integral_negative (UINT64 x _EXC_FLAGS_PARAM
654                                _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
655 #endif
656
657   UINT64 res = 0xbaddbaddbaddbaddull;
658   UINT64 x_sign;
659   int exp;                      // unbiased exponent
660   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
661   BID_UI64DOUBLE tmp1;
662   int x_nr_bits;
663   int q, ind, shift;
664   UINT64 C1;
665   // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
666   UINT128 fstar;
667   UINT128 P128;
668
669   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
670
671   // check for NaNs and infinities
672   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
673     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
674       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
675     else
676       x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
677     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
678       // set invalid flag 
679       *pfpsf |= INVALID_EXCEPTION;
680       // return quiet (SNaN) 
681       res = x & 0xfdffffffffffffffull;
682     } else {    // QNaN
683       res = x;
684     }
685     BID_RETURN (res);
686   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
687     res = x_sign | 0x7800000000000000ull;
688     BID_RETURN (res);
689   }
690   // unpack x
691   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
692     // if the steering bits are 11 (condition will be 0), then
693     // the exponent is G[0:w+1]
694     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
695     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
696     if (C1 > 9999999999999999ull) {     // non-canonical
697       C1 = 0;
698     }
699   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
700     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
701     C1 = (x & MASK_BINARY_SIG1);
702   }
703
704   // if x is 0 or non-canonical
705   if (C1 == 0) {
706     if (exp < 0)
707       exp = 0;
708     res = x_sign | (((UINT64) exp + 398) << 53);
709     BID_RETURN (res);
710   }
711   // x is a finite non-zero number (not 0, non-canonical, or special)
712
713   // return 0 if (exp <= -p)
714   if (exp <= -16) {
715     if (x_sign) {
716       res = 0xb1c0000000000001ull;
717     } else {
718       res = 0x31c0000000000000ull;
719     }
720     BID_RETURN (res);
721   }
722   // q = nr. of decimal digits in x (1 <= q <= 54)
723   //  determine first the nr. of bits in x
724   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
725     q = 16;
726   } else {      // if x < 2^53
727     tmp1.d = (double) C1;       // exact conversion
728     x_nr_bits =
729       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
730     q = nr_digits[x_nr_bits - 1].digits;
731     if (q == 0) {
732       q = nr_digits[x_nr_bits - 1].digits1;
733       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
734         q++;
735     }
736   }
737
738   if (exp >= 0) {       // -exp <= 0
739     // the argument is an integer already
740     res = x;
741     BID_RETURN (res);
742   } else if ((q + exp) > 0) {   // exp < 0 and 1 <= -exp < q
743     // need to shift right -exp digits from the coefficient; the exp will be 0
744     ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
745     // chop off ind digits from the lower part of C1 
746     // C1 fits in 64 bits
747     // calculate C* and f*
748     // C* is actually floor(C*) in this case
749     // C* and f* need shifting and masking, as shown by
750     // shiftright128[] and maskhigh128[]
751     // 1 <= x <= 16
752     // kx = 10^(-x) = ten2mk64[ind - 1]
753     // C* = C1 * 10^(-x)
754     // the approximation of 10^(-x) was rounded up to 64 bits
755     __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
756
757     // C* = floor(C*) (logical right shift; C has p decimal digits,
758     //       correct by Property 1)
759     // if (0 < f* < 10^(-x)) then the result is exact
760     // n = C* * 10^(e+x)  
761
762     if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
763       res = P128.w[1];
764       fstar.w[1] = 0;
765       fstar.w[0] = P128.w[0];
766     } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
767       shift = shiftright128[ind - 1];   // 3 <= shift <= 63
768       res = (P128.w[1] >> shift);
769       fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
770       fstar.w[0] = P128.w[0];
771     }
772     // if (f* > 10^(-x)) then the result is inexact
773     if (x_sign
774         && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
775       // if negative and not exact, increment magnitude
776       res++;
777     }
778     // set exponent to zero as it was negative before.
779     res = x_sign | 0x31c0000000000000ull | res;
780     BID_RETURN (res);
781   } else {      // if exp < 0 and q + exp <= 0
782     // the result is +0 or -1
783     if (x_sign) {
784       res = 0xb1c0000000000001ull;
785     } else {
786       res = 0x31c0000000000000ull;
787     }
788     BID_RETURN (res);
789   }
790 }
791
792 /*****************************************************************************
793  *  BID64_round_integral_positive
794  ****************************************************************************/
795
796 #if DECIMAL_CALL_BY_REFERENCE
797 void
798 bid64_round_integral_positive (UINT64 * pres,
799                                UINT64 *
800                                px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
801                                _EXC_INFO_PARAM) {
802   UINT64 x = *px;
803 #else
804 UINT64
805 bid64_round_integral_positive (UINT64 x _EXC_FLAGS_PARAM
806                                _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
807 #endif
808
809   UINT64 res = 0xbaddbaddbaddbaddull;
810   UINT64 x_sign;
811   int exp;                      // unbiased exponent
812   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
813   BID_UI64DOUBLE tmp1;
814   int x_nr_bits;
815   int q, ind, shift;
816   UINT64 C1;
817   // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
818   UINT128 fstar;
819   UINT128 P128;
820
821   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
822
823   // check for NaNs and infinities
824   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
825     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
826       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
827     else
828       x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
829     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
830       // set invalid flag 
831       *pfpsf |= INVALID_EXCEPTION;
832       // return quiet (SNaN) 
833       res = x & 0xfdffffffffffffffull;
834     } else {    // QNaN
835       res = x;
836     }
837     BID_RETURN (res);
838   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
839     res = x_sign | 0x7800000000000000ull;
840     BID_RETURN (res);
841   }
842   // unpack x
843   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
844     // if the steering bits are 11 (condition will be 0), then
845     // the exponent is G[0:w+1]
846     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
847     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
848     if (C1 > 9999999999999999ull) {     // non-canonical
849       C1 = 0;
850     }
851   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
852     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
853     C1 = (x & MASK_BINARY_SIG1);
854   }
855
856   // if x is 0 or non-canonical
857   if (C1 == 0) {
858     if (exp < 0)
859       exp = 0;
860     res = x_sign | (((UINT64) exp + 398) << 53);
861     BID_RETURN (res);
862   }
863   // x is a finite non-zero number (not 0, non-canonical, or special)
864
865   // return 0 if (exp <= -p)
866   if (exp <= -16) {
867     if (x_sign) {
868       res = 0xb1c0000000000000ull;
869     } else {
870       res = 0x31c0000000000001ull;
871     }
872     BID_RETURN (res);
873   }
874   // q = nr. of decimal digits in x (1 <= q <= 54)
875   //  determine first the nr. of bits in x
876   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
877     q = 16;
878   } else {      // if x < 2^53
879     tmp1.d = (double) C1;       // exact conversion
880     x_nr_bits =
881       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
882     q = nr_digits[x_nr_bits - 1].digits;
883     if (q == 0) {
884       q = nr_digits[x_nr_bits - 1].digits1;
885       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
886         q++;
887     }
888   }
889
890   if (exp >= 0) {       // -exp <= 0
891     // the argument is an integer already
892     res = x;
893     BID_RETURN (res);
894   } else if ((q + exp) > 0) {   // exp < 0 and 1 <= -exp < q
895     // need to shift right -exp digits from the coefficient; the exp will be 0
896     ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
897     // chop off ind digits from the lower part of C1 
898     // C1 fits in 64 bits
899     // calculate C* and f*
900     // C* is actually floor(C*) in this case
901     // C* and f* need shifting and masking, as shown by
902     // shiftright128[] and maskhigh128[]
903     // 1 <= x <= 16
904     // kx = 10^(-x) = ten2mk64[ind - 1]
905     // C* = C1 * 10^(-x)
906     // the approximation of 10^(-x) was rounded up to 64 bits
907     __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
908
909     // C* = floor(C*) (logical right shift; C has p decimal digits,
910     //       correct by Property 1)
911     // if (0 < f* < 10^(-x)) then the result is exact
912     // n = C* * 10^(e+x)  
913
914     if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
915       res = P128.w[1];
916       fstar.w[1] = 0;
917       fstar.w[0] = P128.w[0];
918     } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
919       shift = shiftright128[ind - 1];   // 3 <= shift <= 63
920       res = (P128.w[1] >> shift);
921       fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
922       fstar.w[0] = P128.w[0];
923     }
924     // if (f* > 10^(-x)) then the result is inexact
925     if (!x_sign
926         && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
927       // if positive and not exact, increment magnitude
928       res++;
929     }
930     // set exponent to zero as it was negative before.
931     res = x_sign | 0x31c0000000000000ull | res;
932     BID_RETURN (res);
933   } else {      // if exp < 0 and q + exp <= 0
934     // the result is -0 or +1
935     if (x_sign) {
936       res = 0xb1c0000000000000ull;
937     } else {
938       res = 0x31c0000000000001ull;
939     }
940     BID_RETURN (res);
941   }
942 }
943
944 /*****************************************************************************
945  *  BID64_round_integral_zero
946  ****************************************************************************/
947
948 #if DECIMAL_CALL_BY_REFERENCE
949 void
950 bid64_round_integral_zero (UINT64 * pres,
951                            UINT64 *
952                            px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
953                            _EXC_INFO_PARAM) {
954   UINT64 x = *px;
955 #else
956 UINT64
957 bid64_round_integral_zero (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
958                            _EXC_INFO_PARAM) {
959 #endif
960
961   UINT64 res = 0xbaddbaddbaddbaddull;
962   UINT64 x_sign;
963   int exp;                      // unbiased exponent
964   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
965   BID_UI64DOUBLE tmp1;
966   int x_nr_bits;
967   int q, ind, shift;
968   UINT64 C1;
969   // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
970   UINT128 P128;
971
972   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
973
974   // check for NaNs and infinities
975   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
976     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
977       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
978     else
979       x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
980     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
981       // set invalid flag 
982       *pfpsf |= INVALID_EXCEPTION;
983       // return quiet (SNaN) 
984       res = x & 0xfdffffffffffffffull;
985     } else {    // QNaN
986       res = x;
987     }
988     BID_RETURN (res);
989   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
990     res = x_sign | 0x7800000000000000ull;
991     BID_RETURN (res);
992   }
993   // unpack x
994   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
995     // if the steering bits are 11 (condition will be 0), then
996     // the exponent is G[0:w+1]
997     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
998     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
999     if (C1 > 9999999999999999ull) {     // non-canonical
1000       C1 = 0;
1001     }
1002   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1003     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1004     C1 = (x & MASK_BINARY_SIG1);
1005   }
1006
1007   // if x is 0 or non-canonical
1008   if (C1 == 0) {
1009     if (exp < 0)
1010       exp = 0;
1011     res = x_sign | (((UINT64) exp + 398) << 53);
1012     BID_RETURN (res);
1013   }
1014   // x is a finite non-zero number (not 0, non-canonical, or special)
1015
1016   // return 0 if (exp <= -p)
1017   if (exp <= -16) {
1018     res = x_sign | 0x31c0000000000000ull;
1019     BID_RETURN (res);
1020   }
1021   // q = nr. of decimal digits in x (1 <= q <= 54)
1022   //  determine first the nr. of bits in x
1023   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
1024     q = 16;
1025   } else {      // if x < 2^53
1026     tmp1.d = (double) C1;       // exact conversion
1027     x_nr_bits =
1028       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1029     q = nr_digits[x_nr_bits - 1].digits;
1030     if (q == 0) {
1031       q = nr_digits[x_nr_bits - 1].digits1;
1032       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1033         q++;
1034     }
1035   }
1036
1037   if (exp >= 0) {       // -exp <= 0
1038     // the argument is an integer already
1039     res = x;
1040     BID_RETURN (res);
1041   } else if ((q + exp) >= 0) {  // exp < 0 and 1 <= -exp <= q
1042     // need to shift right -exp digits from the coefficient; the exp will be 0
1043     ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1044     // chop off ind digits from the lower part of C1 
1045     // C1 fits in 127 bits
1046     // calculate C* and f*
1047     // C* is actually floor(C*) in this case
1048     // C* and f* need shifting and masking, as shown by
1049     // shiftright128[] and maskhigh128[]
1050     // 1 <= x <= 16
1051     // kx = 10^(-x) = ten2mk64[ind - 1]
1052     // C* = C1 * 10^(-x)
1053     // the approximation of 10^(-x) was rounded up to 64 bits
1054     __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1055
1056     // C* = floor(C*) (logical right shift; C has p decimal digits,
1057     //       correct by Property 1)
1058     // if (0 < f* < 10^(-x)) then the result is exact
1059     // n = C* * 10^(e+x)  
1060
1061     if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1062       res = P128.w[1];
1063       // redundant fstar.w[1] = 0;
1064       // redundant fstar.w[0] = P128.w[0];
1065     } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1066       shift = shiftright128[ind - 1];   // 3 <= shift <= 63
1067       res = (P128.w[1] >> shift);
1068       // redundant fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
1069       // redundant fstar.w[0] = P128.w[0];
1070     }
1071     // if (f* > 10^(-x)) then the result is inexact
1072     // if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind-1])){
1073     //   // redundant
1074     // }
1075     // set exponent to zero as it was negative before.
1076     res = x_sign | 0x31c0000000000000ull | res;
1077     BID_RETURN (res);
1078   } else {      // if exp < 0 and q + exp < 0
1079     // the result is +0 or -0
1080     res = x_sign | 0x31c0000000000000ull;
1081     BID_RETURN (res);
1082   }
1083 }
1084
1085 /*****************************************************************************
1086  *  BID64_round_integral_nearest_away
1087  ****************************************************************************/
1088
1089 #if DECIMAL_CALL_BY_REFERENCE
1090 void
1091 bid64_round_integral_nearest_away (UINT64 * pres,
1092                                    UINT64 *
1093                                    px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1094                                    _EXC_INFO_PARAM) {
1095   UINT64 x = *px;
1096 #else
1097 UINT64
1098 bid64_round_integral_nearest_away (UINT64 x _EXC_FLAGS_PARAM
1099                                    _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1100 #endif
1101
1102   UINT64 res = 0xbaddbaddbaddbaddull;
1103   UINT64 x_sign;
1104   int exp;                      // unbiased exponent
1105   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1106   BID_UI64DOUBLE tmp1;
1107   int x_nr_bits;
1108   int q, ind, shift;
1109   UINT64 C1;
1110   UINT128 P128;
1111
1112   x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
1113
1114   // check for NaNs and infinities
1115   if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
1116     if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
1117       x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
1118     else
1119       x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
1120     if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
1121       // set invalid flag 
1122       *pfpsf |= INVALID_EXCEPTION;
1123       // return quiet (SNaN) 
1124       res = x & 0xfdffffffffffffffull;
1125     } else {    // QNaN
1126       res = x;
1127     }
1128     BID_RETURN (res);
1129   } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
1130     res = x_sign | 0x7800000000000000ull;
1131     BID_RETURN (res);
1132   }
1133   // unpack x
1134   if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1135     // if the steering bits are 11 (condition will be 0), then
1136     // the exponent is G[0:w+1]
1137     exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
1138     C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1139     if (C1 > 9999999999999999ull) {     // non-canonical
1140       C1 = 0;
1141     }
1142   } else {      // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1143     exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1144     C1 = (x & MASK_BINARY_SIG1);
1145   }
1146
1147   // if x is 0 or non-canonical
1148   if (C1 == 0) {
1149     if (exp < 0)
1150       exp = 0;
1151     res = x_sign | (((UINT64) exp + 398) << 53);
1152     BID_RETURN (res);
1153   }
1154   // x is a finite non-zero number (not 0, non-canonical, or special)
1155
1156   // return 0 if (exp <= -(p+1))
1157   if (exp <= -17) {
1158     res = x_sign | 0x31c0000000000000ull;
1159     BID_RETURN (res);
1160   }
1161   // q = nr. of decimal digits in x (1 <= q <= 54)
1162   //  determine first the nr. of bits in x
1163   if (C1 >= 0x0020000000000000ull) {    // x >= 2^53
1164     q = 16;
1165   } else {      // if x < 2^53
1166     tmp1.d = (double) C1;       // exact conversion
1167     x_nr_bits =
1168       1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1169     q = nr_digits[x_nr_bits - 1].digits;
1170     if (q == 0) {
1171       q = nr_digits[x_nr_bits - 1].digits1;
1172       if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1173         q++;
1174     }
1175   }
1176
1177   if (exp >= 0) {       // -exp <= 0
1178     // the argument is an integer already
1179     res = x;
1180     BID_RETURN (res);
1181   } else if ((q + exp) >= 0) {  // exp < 0 and 1 <= -exp <= q
1182     // need to shift right -exp digits from the coefficient; the exp will be 0
1183     ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1184     // chop off ind digits from the lower part of C1 
1185     // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
1186     // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
1187     C1 = C1 + midpoint64[ind - 1];
1188     // calculate C* and f*
1189     // C* is actually floor(C*) in this case
1190     // C* and f* need shifting and masking, as shown by
1191     // shiftright128[] and maskhigh128[]
1192     // 1 <= x <= 16
1193     // kx = 10^(-x) = ten2mk64[ind - 1]
1194     // C* = (C1 + 1/2 * 10^x) * 10^(-x)
1195     // the approximation of 10^(-x) was rounded up to 64 bits
1196     __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1197
1198     // if (0 < f* < 10^(-x)) then the result is a midpoint
1199     //   C* = floor(C*) - logical right shift; C* has p decimal digits, 
1200     //       correct by Prop. 1)
1201     // else
1202     //   C* = floor(C*) (logical right shift; C has p decimal digits,
1203     //       correct by Property 1)
1204     // n = C* * 10^(e+x)
1205
1206     if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1207       res = P128.w[1];
1208     } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1209       shift = shiftright128[ind - 1];   // 3 <= shift <= 63
1210       res = (P128.w[1] >> shift);
1211     }
1212     // midpoints are already rounded correctly
1213     // set exponent to zero as it was negative before.
1214     res = x_sign | 0x31c0000000000000ull | res;
1215     BID_RETURN (res);
1216   } else {      // if exp < 0 and q + exp < 0
1217     // the result is +0 or -0
1218     res = x_sign | 0x31c0000000000000ull;
1219     BID_RETURN (res);
1220   }
1221 }