1 /******************************************************************************
2   Copyright (c) 2007-2011, Intel Corp.
3   All rights reserved.
4 
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7 
8     * Redistributions of source code must retain the above copyright notice,
9       this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13     * Neither the name of Intel Corporation nor the names of its contributors
14       may be used to endorse or promote products derived from this software
15       without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27   THE POSSIBILITY OF SUCH DAMAGE.
28 ******************************************************************************/
29 
30 #include "bid_internal.h"
31 
32 /*****************************************************************************
33  *  BID32_to_int64_rnint
34  ****************************************************************************/
35 
36 #if DECIMAL_CALL_BY_REFERENCE
37 void
bid32_to_int64_rnint(BID_SINT64 * pres,BID_UINT32 * px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)38 bid32_to_int64_rnint (BID_SINT64 * pres, BID_UINT32 * px
39 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
40 		      _EXC_INFO_PARAM) {
41   BID_UINT32 x = *px;
42 #else
43 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_rnint, 32)
44 BID_SINT64
45 bid32_to_int64_rnint (BID_UINT32 x
46 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
47 		      _EXC_INFO_PARAM) {
48 #endif
49   BID_SINT64 res;
50   BID_UINT32 x_sign;
51   BID_UINT32 x_exp;
52   int exp; // unbiased exponent
53   // Note: C1 represents x_significand (BID_UINT32)
54   BID_UI32FLOAT tmp1;
55   unsigned int x_nr_bits;
56   int q, ind, shift;
57   BID_UINT32 C1;
58   BID_UINT128 C;
59   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
60   BID_UINT128 fstar;
61   BID_UINT128 P128;
62 
63   // check for NaN or Infinity
64   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
65     // set invalid flag
66     *pfpsf |= BID_INVALID_EXCEPTION;
67     // return Integer Indefinite
68     res = 0x8000000000000000ull;
69     BID_RETURN (res);
70   }
71   // unpack x
72   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
73   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
74   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
75     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
76     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
77     if (C1 > 9999999) { // non-canonical
78       x_exp = 0;
79       C1 = 0;
80     }
81   } else {
82     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
83     C1 = x & MASK_BINARY_SIG1_32;
84   }
85 
86   // check for zeros (possibly from non-canonical values)
87   if (C1 == 0x0) {
88     // x is 0
89     res = 0x00000000;
90     BID_RETURN (res);
91   }
92   // x is not special and is not zero
93 
94   // q = nr. of decimal digits in x (1 <= q <= 7)
95   //  determine first the nr. of bits in x
96   tmp1.f = (float) C1; // exact conversion
97   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
98   q = bid_nr_digits[x_nr_bits - 1].digits;
99   if (q == 0) {
100     q = bid_nr_digits[x_nr_bits - 1].digits1;
101     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
102       q++;
103   }
104   exp = x_exp - 101; // unbiased exponent
105 
106   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
107     // set invalid flag
108     *pfpsf |= BID_INVALID_EXCEPTION;
109     // return Integer Indefinite
110     res = 0x8000000000000000ull;
111     BID_RETURN (res);
112   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
113     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
114     // so x rounded to an integer may or may not fit in a signed 64-bit int
115     // the cases that do not fit are identified here; the ones that fit
116     // fall through and will be handled with other cases further,
117     // under '1 <= q + exp <= 19'
118     if (x_sign) { // if n < 0 and q + exp = 19
119       // if n < -2^63 - 1/2 then n is too large
120       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63+1/2
121       // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=7
122       // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=7
123       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
124       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
125       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
126       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
127 	// set invalid flag
128 	*pfpsf |= BID_INVALID_EXCEPTION;
129 	// return Integer Indefinite
130 	res = 0x8000000000000000ull;
131 	BID_RETURN (res);
132       }
133       // else cases that can be rounded to a 64-bit int fall through
134       // to '1 <= q + exp <= 19'
135     } else { // if n > 0 and q + exp = 19
136       // if n >= 2^63 - 1/2 then n is too large
137       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63-1/2
138       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=7
139       // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=7
140       C.w[1] = 0x0000000000000004ull;
141       C.w[0] = 0xfffffffffffffffbull;
142       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
143       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
144       if (C.w[1] > 0x04ull ||
145 	  (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
146 	// set invalid flag
147 	*pfpsf |= BID_INVALID_EXCEPTION;
148 	// return Integer Indefinite
149 	res = 0x8000000000000000ull;
150 	BID_RETURN (res);
151       }
152       // else cases that can be rounded to a 64-bit int fall through
153       // to '1 <= q + exp <= 19'
154     }	// end else if n > 0 and q + exp = 19
155   }	// end else if ((q + exp) == 19)
156 
157   // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
158   // Note: some of the cases tested for above fall through to this point
159   if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
160     // return 0
161     res = 0x0000000000000000ull;
162     BID_RETURN (res);
163   } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
164     // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
165     //   res = 0
166     // else
167     //   res = +/-1
168     ind = q - 1; // 0 <= ind <= 6
169     if ((BID_UINT64)C1 <= bid_midpoint64[ind]) {
170       res = 0x0000000000000000ull; // return 0
171     } else if (x_sign) { // n < 0
172       res = 0xffffffffffffffffull; // return -1
173     } else { // n > 0
174       res = 0x0000000000000001ull; // return +1
175     }
176   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
177     // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
178     // to nearest to a 64-bit signed integer
179     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
180       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
181       // chop off ind digits from the lower part of C1
182       // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
183       C1 = C1 + (BID_UINT32)bid_midpoint64[ind - 1];
184       // calculate C* and f*
185       // C* is actually floor(C*) in this case
186       // C* and f* need shifting and masking, as shown by
187       // bid_shiftright128[] and bid_maskhigh128[]
188       // 1 <= x <= 6
189       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
190       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
191       // the approximation of 10^(-x) was rounded up to 54 bits
192       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
193       Cstar = P128.w[1];
194       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
195       fstar.w[0] = P128.w[0];
196       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
197       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
198       // if (0 < f* < 10^(-x)) then the result is a midpoint
199       //   if floor(C*) is even then C* = floor(C*) - logical right
200       //       shift; C* has p decimal digits, correct by Prop. 1)
201       //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
202       //       shift; C* has p decimal digits, correct by Pr. 1)
203       // else
204       //   C* = floor(C*) (logical right shift; C has p decimal digits,
205       //       correct by Property 1)
206       // n = C* * 10^(e+x)
207 
208       // shift right C* by Ex-64 = bid_shiftright128[ind]
209       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
210       Cstar = Cstar >> shift;
211 
212       // if the result was a midpoint it was rounded away from zero, so
213       // it will need a correction
214       // check for midpoints
215       if ((fstar.w[1] == 0) && fstar.w[0] &&
216 	  (fstar.w[0] <= bid_ten2mk128trunc[ind - 1].w[1])) {
217 	// bid_ten2mk128trunc[ind -1].w[1] is identical to
218 	// bid_ten2mk128[ind -1].w[1]
219 	// the result is a midpoint; round to nearest
220 	if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
221 	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
222 	  Cstar--; // Cstar is now even
223 	}	// else MP in [ODD, EVEN]
224       }
225       if (x_sign)
226 	res = -Cstar;
227       else
228 	res = Cstar;
229     } else if (exp == 0) {
230       // 1 <= q <= 7
231       // res = +/-C (exact)
232       if (x_sign)
233 	res = -(BID_UINT64)C1;
234       else
235 	res = C1;
236     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
237       // (the upper limit of 20 on q + exp is due to the fact that
238       // +/-C * 10^exp is guaranteed to fit in 64 bits)
239       // res = +/-C * 10^exp (exact)
240       if (x_sign)
241 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
242       else
243 	res = C1 * bid_ten2k64[exp];
244     }
245   }
246   BID_RETURN (res);
247 }
248 
249 /*****************************************************************************
250  *  BID32_to_int64_xrnint
251  ****************************************************************************/
252 
253 #if DECIMAL_CALL_BY_REFERENCE
254 void
255 bid32_to_int64_xrnint (BID_SINT64 * pres, BID_UINT32 * px
256 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
257 		       _EXC_INFO_PARAM) {
258   BID_UINT32 x = *px;
259 #else
260 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_xrnint, 32)
261 BID_SINT64
262 bid32_to_int64_xrnint (BID_UINT32 x
263 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
264 		       _EXC_INFO_PARAM) {
265 #endif
266   BID_SINT64 res;
267   BID_UINT32 x_sign;
268   BID_UINT32 x_exp;
269   int exp; // unbiased exponent
270   // Note: C1 represents x_significand (BID_UINT32)
271   BID_UINT64 tmp64;
272   BID_UI32FLOAT tmp1;
273   unsigned int x_nr_bits;
274   int q, ind, shift;
275   BID_UINT32 C1;
276   BID_UINT128 C;
277   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
278   BID_UINT128 fstar;
279   BID_UINT128 P128;
280 
281   // check for NaN or Infinity
282   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
283     // set invalid flag
284     *pfpsf |= BID_INVALID_EXCEPTION;
285     // return Integer Indefinite
286     res = 0x8000000000000000ull;
287     BID_RETURN (res);
288   }
289   // unpack x
290   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
291   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
292   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
293     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
294     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
295     if (C1 > 9999999) { // non-canonical
296       x_exp = 0;
297       C1 = 0;
298     }
299   } else {
300     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
301     C1 = x & MASK_BINARY_SIG1_32;
302   }
303 
304   // check for zeros (possibly from non-canonical values)
305   if (C1 == 0x0) {
306     // x is 0
307     res = 0x00000000;
308     BID_RETURN (res);
309   }
310   // x is not special and is not zero
311 
312   // q = nr. of decimal digits in x (1 <= q <= 7)
313   //  determine first the nr. of bits in x
314   tmp1.f = (float) C1; // exact conversion
315   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
316   q = bid_nr_digits[x_nr_bits - 1].digits;
317   if (q == 0) {
318     q = bid_nr_digits[x_nr_bits - 1].digits1;
319     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
320       q++;
321   }
322   exp = x_exp - 101; // unbiased exponent
323 
324   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
325     // set invalid flag
326     *pfpsf |= BID_INVALID_EXCEPTION;
327     // return Integer Indefinite
328     res = 0x8000000000000000ull;
329     BID_RETURN (res);
330   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
331     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
332     // so x rounded to an integer may or may not fit in a signed 64-bit int
333     // the cases that do not fit are identified here; the ones that fit
334     // fall through and will be handled with other cases further,
335     // under '1 <= q + exp <= 19'
336     if (x_sign) { // if n < 0 and q + exp = 19
337       // if n < -2^63 - 1/2 then n is too large
338       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63+1/2
339       // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=7
340       // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=7
341       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
342       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
343       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
344       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
345 	// set invalid flag
346 	*pfpsf |= BID_INVALID_EXCEPTION;
347 	// return Integer Indefinite
348 	res = 0x8000000000000000ull;
349 	BID_RETURN (res);
350       }
351       // else cases that can be rounded to a 64-bit int fall through
352       // to '1 <= q + exp <= 19'
353     } else { // if n > 0 and q + exp = 19
354       // if n >= 2^63 - 1/2 then n is too large
355       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63-1/2
356       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=7
357       // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=7
358       C.w[1] = 0x0000000000000004ull;
359       C.w[0] = 0xfffffffffffffffbull;
360       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
361       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
362       if (C.w[1] > 0x04ull ||
363 	  (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
364 	// set invalid flag
365 	*pfpsf |= BID_INVALID_EXCEPTION;
366 	// return Integer Indefinite
367 	res = 0x8000000000000000ull;
368 	BID_RETURN (res);
369       }
370       // else cases that can be rounded to a 64-bit int fall through
371       // to '1 <= q + exp <= 19'
372     }	// end else if n > 0 and q + exp = 19
373   }	// end else if ((q + exp) == 19)
374 
375   // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
376   // Note: some of the cases tested for above fall through to this point
377   if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
378     // set inexact flag
379     *pfpsf |= BID_INEXACT_EXCEPTION;
380     // return 0
381     res = 0x0000000000000000ull;
382     BID_RETURN (res);
383   } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
384     // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
385     //   res = 0
386     // else
387     //   res = +/-1
388     ind = q - 1; // 0 <= ind <= 6
389     if ((BID_UINT64)C1 <= bid_midpoint64[ind]) {
390       res = 0x0000000000000000ull; // return 0
391     } else if (x_sign) { // n < 0
392       res = 0xffffffffffffffffull; // return -1
393     } else { // n > 0
394       res = 0x0000000000000001ull; // return +1
395     }
396     // set inexact flag
397     *pfpsf |= BID_INEXACT_EXCEPTION;
398   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
399     // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
400     // to nearest to a 64-bit signed integer
401     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
402       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
403       // chop off ind digits from the lower part of C1
404       // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
405       C1 = C1 + (BID_UINT32)bid_midpoint64[ind - 1];
406       // calculate C* and f*
407       // C* is actually floor(C*) in this case
408       // C* and f* need shifting and masking, as shown by
409       // bid_shiftright128[] and bid_maskhigh128[]
410       // 1 <= x <= 6
411       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
412       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
413       // the approximation of 10^(-x) was rounded up to 54 bits
414       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
415       Cstar = P128.w[1];
416       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
417       fstar.w[0] = P128.w[0];
418       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
419       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
420       // if (0 < f* < 10^(-x)) then the result is a midpoint
421       //   if floor(C*) is even then C* = floor(C*) - logical right
422       //       shift; C* has p decimal digits, correct by Prop. 1)
423       //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
424       //       shift; C* has p decimal digits, correct by Pr. 1)
425       // else
426       //   C* = floor(C*) (logical right shift; C has p decimal digits,
427       //       correct by Property 1)
428       // n = C* * 10^(e+x)
429 
430       // shift right C* by Ex-64 = bid_shiftright128[ind]
431       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
432       Cstar = Cstar >> shift;
433       // determine inexactness of the rounding of C*
434       // if (0 < f* - 1/2 < 10^(-x)) then
435       //   the result is exact
436       // else // if (f* - 1/2 > T*) then
437       //   the result is inexact
438       if (ind - 1 <= 2) {
439 	if (fstar.w[0] > 0x8000000000000000ull) {
440 	  // f* > 1/2 and the result may be exact
441 	  tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
442 	  if ((tmp64 > bid_ten2mk128trunc[ind - 1].w[1])) {
443 	    // bid_ten2mk128trunc[ind -1].w[1] is identical to
444 	    // bid_ten2mk128[ind -1].w[1]
445 	    // set the inexact flag
446 	    *pfpsf |= BID_INEXACT_EXCEPTION;
447 	  }	// else the result is exact
448 	} else { // the result is inexact; f2* <= 1/2
449 	  // set the inexact flag
450 	  *pfpsf |= BID_INEXACT_EXCEPTION;
451 	}
452       } else { // if 3 <= ind - 1 <= 14
453 	if (fstar.w[1] > bid_onehalf128[ind - 1] ||
454 	    (fstar.w[1] == bid_onehalf128[ind - 1] && fstar.w[0])) {
455 	  // f2* > 1/2 and the result may be exact
456 	  // Calculate f2* - 1/2
457 	  tmp64 = fstar.w[1] - bid_onehalf128[ind - 1];
458 	  if (tmp64 || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
459 	    // bid_ten2mk128trunc[ind -1].w[1] is identical to
460 	    // bid_ten2mk128[ind -1].w[1]
461 	    // set the inexact flag
462 	    *pfpsf |= BID_INEXACT_EXCEPTION;
463 	  }	// else the result is exact
464 	} else { // the result is inexact; f2* <= 1/2
465 	  // set the inexact flag
466 	  *pfpsf |= BID_INEXACT_EXCEPTION;
467 	}
468       }
469 
470       // if the result was a midpoint it was rounded away from zero, so
471       // it will need a correction
472       // check for midpoints
473       if ((fstar.w[1] == 0) && fstar.w[0] &&
474 	  (fstar.w[0] <= bid_ten2mk128trunc[ind - 1].w[1])) {
475 	// bid_ten2mk128trunc[ind -1].w[1] is identical to
476 	// bid_ten2mk128[ind -1].w[1]
477 	// the result is a midpoint; round to nearest
478 	if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
479 	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
480 	  Cstar--; // Cstar is now even
481 	}	// else MP in [ODD, EVEN]
482       }
483       if (x_sign)
484 	res = -Cstar;
485       else
486 	res = Cstar;
487     } else if (exp == 0) {
488       // 1 <= q <= 7
489       // res = +/-C (exact)
490       if (x_sign)
491 	res = -(BID_UINT64)C1;
492       else
493 	res = C1;
494     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
495       // (the upper limit of 20 on q + exp is due to the fact that
496       // +/-C * 10^exp is guaranteed to fit in 64 bits)
497       // res = +/-C * 10^exp (exact)
498       if (x_sign)
499 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
500       else
501 	res = C1 * bid_ten2k64[exp];
502     }
503   }
504   BID_RETURN (res);
505 }
506 
507 /*****************************************************************************
508  *  BID32_to_int64_floor
509  ****************************************************************************/
510 
511 #if DECIMAL_CALL_BY_REFERENCE
512 void
513 bid32_to_int64_floor (BID_SINT64 * pres, BID_UINT32 * px
514 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
515 		      _EXC_INFO_PARAM) {
516   BID_UINT32 x = *px;
517 #else
518 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_floor, 32)
519 BID_SINT64
520 bid32_to_int64_floor (BID_UINT32 x
521 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
522 		      _EXC_INFO_PARAM) {
523 #endif
524   BID_SINT64 res;
525   BID_UINT32 x_sign;
526   BID_UINT32 x_exp;
527   int exp; // unbiased exponent
528   // Note: C1 represents x_significand (BID_UINT32)
529   BID_UI32FLOAT tmp1;
530   unsigned int x_nr_bits;
531   int q, ind, shift;
532   BID_UINT32 C1;
533   BID_UINT128 C;
534   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
535   BID_UINT128 fstar;
536   BID_UINT128 P128;
537 
538   // check for NaN or Infinity
539   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
540     // set invalid flag
541     *pfpsf |= BID_INVALID_EXCEPTION;
542     // return Integer Indefinite
543     res = 0x8000000000000000ull;
544     BID_RETURN (res);
545   }
546   // unpack x
547   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
548   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
549   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
550     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
551     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
552     if (C1 > 9999999) { // non-canonical
553       x_exp = 0;
554       C1 = 0;
555     }
556   } else {
557     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
558     C1 = x & MASK_BINARY_SIG1_32;
559   }
560 
561   // check for zeros (possibly from non-canonical values)
562   if (C1 == 0x0) {
563     // x is 0
564     res = 0x0000000000000000ull;
565     BID_RETURN (res);
566   }
567   // x is not special and is not zero
568 
569   // q = nr. of decimal digits in x (1 <= q <= 7)
570   //  determine first the nr. of bits in x
571   tmp1.f = (float) C1; // exact conversion
572   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
573   q = bid_nr_digits[x_nr_bits - 1].digits;
574   if (q == 0) {
575     q = bid_nr_digits[x_nr_bits - 1].digits1;
576     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
577       q++;
578   }
579   exp = x_exp - 101; // unbiased exponent
580 
581   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
582     // set invalid flag
583     *pfpsf |= BID_INVALID_EXCEPTION;
584     // return Integer Indefinite
585     res = 0x8000000000000000ull;
586     BID_RETURN (res);
587   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
588     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
589     // so x rounded to an integer may or may not fit in a signed 64-bit int
590     // the cases that do not fit are identified here; the ones that fit
591     // fall through and will be handled with other cases further,
592     // under '1 <= q + exp <= 19'
593     if (x_sign) { // if n < 0 and q + exp = 19
594       // if n < -2^63 then n is too large
595       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63
596       // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=7
597       // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=7
598       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
599       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
600       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
601       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
602 	// set invalid flag
603 	*pfpsf |= BID_INVALID_EXCEPTION;
604 	// return Integer Indefinite
605 	res = 0x8000000000000000ull;
606 	BID_RETURN (res);
607       }
608       // else cases that can be rounded to a 64-bit int fall through
609       // to '1 <= q + exp <= 19'
610     } else { // if n > 0 and q + exp = 19
611       // if n >= 2^63 then n is too large
612       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63
613       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=7
614       // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=7
615       C.w[1] = 0x0000000000000005ull;
616       C.w[0] = 0x0000000000000000ull;
617       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
618       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
619       if (C.w[1] >= 0x05ull) {
620 	// actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
621 	// set invalid flag
622 	*pfpsf |= BID_INVALID_EXCEPTION;
623 	// return Integer Indefinite
624 	res = 0x8000000000000000ull;
625 	BID_RETURN (res);
626       }
627       // else cases that can be rounded to a 64-bit int fall through
628       // to '1 <= q + exp <= 19'
629     }	// end else if n > 0 and q + exp = 19
630   }	// end else if ((q + exp) == 19)
631 
632   // n is not too large to be converted to int64: -2^63 <= n < 2^63
633   // Note: some of the cases tested for above fall through to this point
634   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
635     // return -1 or 0
636     if (x_sign)
637       res = 0xffffffffffffffffull;
638     else
639       res = 0x0000000000000000ull;
640     BID_RETURN (res);
641   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
642     // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
643     // to nearest to a 64-bit signed integer
644     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
645       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
646       // chop off ind digits from the lower part of C1
647       // C1 fits in 64 bits
648       // calculate C* and f*
649       // C* is actually floor(C*) in this case
650       // C* and f* need shifting and masking, as shown by
651       // bid_shiftright128[] and bid_maskhigh128[]
652       // 1 <= x <= 6
653       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
654       // C* = C1 * 10^(-x)
655       // the approximation of 10^(-x) was rounded up to 54 bits
656       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
657       Cstar = P128.w[1];
658       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
659       fstar.w[0] = P128.w[0];
660       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
661       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
662       // C* = floor(C*) (logical right shift; C has p decimal digits,
663       //     correct by Property 1)
664       // n = C* * 10^(e+x)
665 
666       // shift right C* by Ex-64 = bid_shiftright128[ind]
667       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
668       Cstar = Cstar >> shift;
669       // determine inexactness of the rounding of C*
670       // if (0 < f* < 10^(-x)) then
671       //   the result is exact
672       // else // if (f* > T*) then
673       //   the result is inexact
674       if (ind - 1 <= 2) { // fstar.w[1] is 0
675 	if (fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
676 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
677 	  // bid_ten2mk128[ind -1].w[1]
678 	  if (x_sign) { // negative and inexact
679 	    Cstar++;
680 	  }
681 	}	// else the result is exact
682       } else { // if 3 <= ind - 1 <= 14
683 	if (fstar.w[1] || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
684 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
685 	  // bid_ten2mk128[ind -1].w[1]
686 	  if (x_sign) { // negative and inexact
687 	    Cstar++;
688 	  }
689 	}	// else the result is exact
690       }
691 
692       if (x_sign)
693 	res = -Cstar;
694       else
695 	res = Cstar;
696     } else if (exp == 0) {
697       // 1 <= q <= 7
698       // res = +/-C (exact)
699       if (x_sign)
700 	res = -(BID_UINT64)C1;
701       else
702 	res = C1;
703     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
704       // (the upper limit of 20 on q + exp is due to the fact that
705       // +/-C * 10^exp is guaranteed to fit in 64 bits)
706       // res = +/-C * 10^exp (exact)
707       if (x_sign)
708 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
709       else
710 	res = C1 * bid_ten2k64[exp];
711     }
712   }
713   BID_RETURN (res);
714 }
715 
716 /*****************************************************************************
717  *  BID32_to_int64_xfloor
718  ****************************************************************************/
719 
720 #if DECIMAL_CALL_BY_REFERENCE
721 void
722 bid32_to_int64_xfloor (BID_SINT64 * pres, BID_UINT32 * px
723 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
724 		       _EXC_INFO_PARAM) {
725   BID_UINT32 x = *px;
726 #else
727 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_xfloor, 32)
728 BID_SINT64
729 bid32_to_int64_xfloor (BID_UINT32 x
730 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
731 		       _EXC_INFO_PARAM) {
732 #endif
733   BID_SINT64 res;
734   BID_UINT32 x_sign;
735   BID_UINT32 x_exp;
736   int exp; // unbiased exponent
737   // Note: C1 represents x_significand (BID_UINT32)
738   BID_UI32FLOAT tmp1;
739   unsigned int x_nr_bits;
740   int q, ind, shift;
741   BID_UINT32 C1;
742   BID_UINT128 C;
743   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
744   BID_UINT128 fstar;
745   BID_UINT128 P128;
746 
747   // check for NaN or Infinity
748   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
749     // set invalid flag
750     *pfpsf |= BID_INVALID_EXCEPTION;
751     // return Integer Indefinite
752     res = 0x8000000000000000ull;
753     BID_RETURN (res);
754   }
755   // unpack x
756   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
757   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
758   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
759     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
760     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
761     if (C1 > 9999999) { // non-canonical
762       x_exp = 0;
763       C1 = 0;
764     }
765   } else {
766     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
767     C1 = x & MASK_BINARY_SIG1_32;
768   }
769 
770   // check for zeros (possibly from non-canonical values)
771   if (C1 == 0x0) {
772     // x is 0
773     res = 0x0000000000000000ull;
774     BID_RETURN (res);
775   }
776   // x is not special and is not zero
777 
778   // q = nr. of decimal digits in x (1 <= q <= 7)
779   //  determine first the nr. of bits in x
780   tmp1.f = (float) C1; // exact conversion
781   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
782   q = bid_nr_digits[x_nr_bits - 1].digits;
783   if (q == 0) {
784     q = bid_nr_digits[x_nr_bits - 1].digits1;
785     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
786       q++;
787   }
788   exp = x_exp - 101; // unbiased exponent
789 
790   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
791     // set invalid flag
792     *pfpsf |= BID_INVALID_EXCEPTION;
793     // return Integer Indefinite
794     res = 0x8000000000000000ull;
795     BID_RETURN (res);
796   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
797     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
798     // so x rounded to an integer may or may not fit in a signed 64-bit int
799     // the cases that do not fit are identified here; the ones that fit
800     // fall through and will be handled with other cases further,
801     // under '1 <= q + exp <= 19'
802     if (x_sign) { // if n < 0 and q + exp = 19
803       // if n < -2^63 then n is too large
804       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63
805       // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=7
806       // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=7
807       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
808       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
809       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
810       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
811 	// set invalid flag
812 	*pfpsf |= BID_INVALID_EXCEPTION;
813 	// return Integer Indefinite
814 	res = 0x8000000000000000ull;
815 	BID_RETURN (res);
816       }
817       // else cases that can be rounded to a 64-bit int fall through
818       // to '1 <= q + exp <= 19'
819     } else { // if n > 0 and q + exp = 19
820       // if n >= 2^63 then n is too large
821       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63
822       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=7
823       // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=7
824       C.w[1] = 0x0000000000000005ull;
825       C.w[0] = 0x0000000000000000ull;
826       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
827       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
828       if (C.w[1] >= 0x05ull) {
829 	// actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
830 	// set invalid flag
831 	*pfpsf |= BID_INVALID_EXCEPTION;
832 	// return Integer Indefinite
833 	res = 0x8000000000000000ull;
834 	BID_RETURN (res);
835       }
836       // else cases that can be rounded to a 64-bit int fall through
837       // to '1 <= q + exp <= 19'
838     }	// end else if n > 0 and q + exp = 19
839   }	// end else if ((q + exp) == 19)
840 
841   // n is not too large to be converted to int64: -2^63 <= n < 2^63
842   // Note: some of the cases tested for above fall through to this point
843   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
844     // set inexact flag
845     *pfpsf |= BID_INEXACT_EXCEPTION;
846     // return -1 or 0
847     if (x_sign)
848       res = 0xffffffffffffffffull;
849     else
850       res = 0x0000000000000000ull;
851     BID_RETURN (res);
852   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
853     // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
854     // to nearest to a 64-bit signed integer
855     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
856       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
857       // chop off ind digits from the lower part of C1
858       // C1 fits in 64 bits
859       // calculate C* and f*
860       // C* is actually floor(C*) in this case
861       // C* and f* need shifting and masking, as shown by
862       // bid_shiftright128[] and bid_maskhigh128[]
863       // 1 <= x <= 6
864       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
865       // C* = C1 * 10^(-x)
866       // the approximation of 10^(-x) was rounded up to 54 bits
867       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
868       Cstar = P128.w[1];
869       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
870       fstar.w[0] = P128.w[0];
871       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
872       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
873       // C* = floor(C*) (logical right shift; C has p decimal digits,
874       //     correct by Property 1)
875       // n = C* * 10^(e+x)
876 
877       // shift right C* by Ex-64 = bid_shiftright128[ind]
878       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
879       Cstar = Cstar >> shift;
880       // determine inexactness of the rounding of C*
881       // if (0 < f* < 10^(-x)) then
882       //   the result is exact
883       // else // if (f* > T*) then
884       //   the result is inexact
885       if (ind - 1 <= 2) { // fstar.w[1] is 0
886 	if (fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
887 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
888 	  // bid_ten2mk128[ind -1].w[1]
889 	  if (x_sign) { // negative and inexact
890 	    Cstar++;
891 	  }
892 	  // set the inexact flag
893 	  *pfpsf |= BID_INEXACT_EXCEPTION;
894 	}	// else the result is exact
895       } else { // if 3 <= ind - 1 <= 14
896 	if (fstar.w[1] || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
897 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
898 	  // bid_ten2mk128[ind -1].w[1]
899 	  if (x_sign) { // negative and inexact
900 	    Cstar++;
901 	  }
902 	  // set the inexact flag
903 	  *pfpsf |= BID_INEXACT_EXCEPTION;
904 	}	// else the result is exact
905       }
906 
907       if (x_sign)
908 	res = -Cstar;
909       else
910 	res = Cstar;
911     } else if (exp == 0) {
912       // 1 <= q <= 7
913       // res = +/-C (exact)
914       if (x_sign)
915 	res = -(BID_UINT64)C1;
916       else
917 	res = C1;
918     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
919       // (the upper limit of 20 on q + exp is due to the fact that
920       // +/-C * 10^exp is guaranteed to fit in 64 bits)
921       // res = +/-C * 10^exp (exact)
922       if (x_sign)
923 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
924       else
925 	res = C1 * bid_ten2k64[exp];
926     }
927   }
928   BID_RETURN (res);
929 }
930 
931 /*****************************************************************************
932  *  BID32_to_int64_ceil
933  ****************************************************************************/
934 
935 #if DECIMAL_CALL_BY_REFERENCE
936 void
937 bid32_to_int64_ceil (BID_SINT64 * pres, BID_UINT32 * px
938 		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
939 {
940   BID_UINT32 x = *px;
941 #else
942 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_ceil, 32)
943 BID_SINT64
944 bid32_to_int64_ceil (BID_UINT32 x
945 		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
946 {
947 #endif
948   BID_SINT64 res;
949   BID_UINT32 x_sign;
950   BID_UINT32 x_exp;
951   int exp; // unbiased exponent
952   // Note: C1 represents x_significand (BID_UINT32)
953   BID_UI32FLOAT tmp1;
954   unsigned int x_nr_bits;
955   int q, ind, shift;
956   BID_UINT32 C1;
957   BID_UINT128 C;
958   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
959   BID_UINT128 fstar;
960   BID_UINT128 P128;
961 
962   // check for NaN or Infinity
963   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
964     // set invalid flag
965     *pfpsf |= BID_INVALID_EXCEPTION;
966     // return Integer Indefinite
967     res = 0x8000000000000000ull;
968     BID_RETURN (res);
969   }
970   // unpack x
971   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
972   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
973   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
974     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
975     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
976     if (C1 > 9999999) { // non-canonical
977       x_exp = 0;
978       C1 = 0;
979     }
980   } else {
981     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
982     C1 = x & MASK_BINARY_SIG1_32;
983   }
984 
985   // check for zeros (possibly from non-canonical values)
986   if (C1 == 0x0) {
987     // x is 0
988     res = 0x00000000;
989     BID_RETURN (res);
990   }
991   // x is not special and is not zero
992 
993   // q = nr. of decimal digits in x (1 <= q <= 7)
994   //  determine first the nr. of bits in x
995   tmp1.f = (float) C1; // exact conversion
996   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
997   q = bid_nr_digits[x_nr_bits - 1].digits;
998   if (q == 0) {
999     q = bid_nr_digits[x_nr_bits - 1].digits1;
1000     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
1001       q++;
1002   }
1003   exp = x_exp - 101; // unbiased exponent
1004 
1005   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
1006     // set invalid flag
1007     *pfpsf |= BID_INVALID_EXCEPTION;
1008     // return Integer Indefinite
1009     res = 0x8000000000000000ull;
1010     BID_RETURN (res);
1011   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
1012     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1013     // so x rounded to an integer may or may not fit in a signed 64-bit int
1014     // the cases that do not fit are identified here; the ones that fit
1015     // fall through and will be handled with other cases further,
1016     // under '1 <= q + exp <= 19'
1017     if (x_sign) { // if n < 0 and q + exp = 19
1018       // if n <= -2^63 - 1 then n is too large
1019       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1
1020       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=7
1021       // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=7
1022       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1023       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1024       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1025       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1026 	// set invalid flag
1027 	*pfpsf |= BID_INVALID_EXCEPTION;
1028 	// return Integer Indefinite
1029 	res = 0x8000000000000000ull;
1030 	BID_RETURN (res);
1031       }
1032       // else cases that can be rounded to a 64-bit int fall through
1033       // to '1 <= q + exp <= 19'
1034     } else { // if n > 0 and q + exp = 19
1035       // if n > 2^63 - 1 then n is too large
1036       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63 - 1
1037       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=7
1038       // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=7
1039       C.w[1] = 0x0000000000000004ull;
1040       C.w[0] = 0xfffffffffffffff6ull;
1041       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1042       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1043       if (C.w[1] > 0x04ull ||
1044 	  (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
1045 	// set invalid flag
1046 	*pfpsf |= BID_INVALID_EXCEPTION;
1047 	// return Integer Indefinite
1048 	res = 0x8000000000000000ull;
1049 	BID_RETURN (res);
1050       }
1051       // else cases that can be rounded to a 64-bit int fall through
1052       // to '1 <= q + exp <= 19'
1053     }	// end else if n > 0 and q + exp = 19
1054   }	// end else if ((q + exp) == 19)
1055 
1056   // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1057   // Note: some of the cases tested for above fall through to this point
1058   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1059     // return 0 or 1
1060     if (x_sign)
1061       res = 0x00000000;
1062     else
1063       res = 0x00000001;
1064     BID_RETURN (res);
1065   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
1066     // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1067     // to nearest to a 64-bit signed integer
1068     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
1069       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
1070       // chop off ind digits from the lower part of C1
1071       // C1 fits in 64 bits
1072       // calculate C* and f*
1073       // C* is actually floor(C*) in this case
1074       // C* and f* need shifting and masking, as shown by
1075       // bid_shiftright128[] and bid_maskhigh128[]
1076       // 1 <= x <= 6
1077       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
1078       // C* = C1 * 10^(-x)
1079       // the approximation of 10^(-x) was rounded up to 54 bits
1080       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
1081       Cstar = P128.w[1];
1082       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
1083       fstar.w[0] = P128.w[0];
1084       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
1085       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1086       // C* = floor(C*) (logical right shift; C has p decimal digits,
1087       //     correct by Property 1)
1088       // n = C* * 10^(e+x)
1089 
1090       // shift right C* by Ex-64 = bid_shiftright128[ind]
1091       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1092       Cstar = Cstar >> shift;
1093       // determine inexactness of the rounding of C*
1094       // if (0 < f* < 10^(-x)) then
1095       //   the result is exact
1096       // else // if (f* > T*) then
1097       //   the result is inexact
1098       if (ind - 1 <= 2) { // fstar.w[1] is 0
1099 	if (fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1100 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1101 	  // bid_ten2mk128[ind -1].w[1]
1102 	  if (!x_sign) { // positive and inexact
1103 	    Cstar++;
1104 	  }
1105 	}	// else the result is exact
1106       } else { // if 3 <= ind - 1 <= 14
1107 	if (fstar.w[1] || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1108 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1109 	  // bid_ten2mk128[ind -1].w[1]
1110 	  if (!x_sign) { // positive and inexact
1111 	    Cstar++;
1112 	  }
1113 	}	// else the result is exact
1114       }
1115 
1116       if (x_sign)
1117 	res = -Cstar;
1118       else
1119 	res = Cstar;
1120     } else if (exp == 0) {
1121       // 1 <= q <= 7
1122       // res = +/-C (exact)
1123       if (x_sign)
1124 	res = -(BID_UINT64)C1;
1125       else
1126 	res = C1;
1127     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
1128       // (the upper limit of 20 on q + exp is due to the fact that
1129       // +/-C * 10^exp is guaranteed to fit in 64 bits)
1130       // res = +/-C * 10^exp (exact)
1131       if (x_sign)
1132 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
1133       else
1134 	res = C1 * bid_ten2k64[exp];
1135     }
1136   }
1137   BID_RETURN (res);
1138 }
1139 
1140 /*****************************************************************************
1141  *  BID32_to_int64_xceil
1142  ****************************************************************************/
1143 
1144 #if DECIMAL_CALL_BY_REFERENCE
1145 void
1146 bid32_to_int64_xceil (BID_SINT64 * pres, BID_UINT32 * px
1147 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1148 		      _EXC_INFO_PARAM) {
1149   BID_UINT32 x = *px;
1150 #else
1151 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_xceil, 32)
1152 BID_SINT64
1153 bid32_to_int64_xceil (BID_UINT32 x
1154 		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1155 		      _EXC_INFO_PARAM) {
1156 #endif
1157   BID_SINT64 res;
1158   BID_UINT32 x_sign;
1159   BID_UINT32 x_exp;
1160   int exp; // unbiased exponent
1161   // Note: C1 represents x_significand (BID_UINT32)
1162   BID_UI32FLOAT tmp1;
1163   unsigned int x_nr_bits;
1164   int q, ind, shift;
1165   BID_UINT32 C1;
1166   BID_UINT128 C;
1167   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1168   BID_UINT128 fstar;
1169   BID_UINT128 P128;
1170 
1171   // check for NaN or Infinity
1172   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
1173     // set invalid flag
1174     *pfpsf |= BID_INVALID_EXCEPTION;
1175     // return Integer Indefinite
1176     res = 0x8000000000000000ull;
1177     BID_RETURN (res);
1178   }
1179   // unpack x
1180   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
1181   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1182   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
1183     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
1184     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
1185     if (C1 > 9999999) { // non-canonical
1186       x_exp = 0;
1187       C1 = 0;
1188     }
1189   } else {
1190     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
1191     C1 = x & MASK_BINARY_SIG1_32;
1192   }
1193 
1194   // check for zeros (possibly from non-canonical values)
1195   if (C1 == 0x0) {
1196     // x is 0
1197     res = 0x00000000;
1198     BID_RETURN (res);
1199   }
1200   // x is not special and is not zero
1201 
1202   // q = nr. of decimal digits in x (1 <= q <= 7)
1203   //  determine first the nr. of bits in x
1204   tmp1.f = (float) C1; // exact conversion
1205   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
1206   q = bid_nr_digits[x_nr_bits - 1].digits;
1207   if (q == 0) {
1208     q = bid_nr_digits[x_nr_bits - 1].digits1;
1209     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
1210       q++;
1211   }
1212   exp = x_exp - 101; // unbiased exponent
1213 
1214   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
1215     // set invalid flag
1216     *pfpsf |= BID_INVALID_EXCEPTION;
1217     // return Integer Indefinite
1218     res = 0x8000000000000000ull;
1219     BID_RETURN (res);
1220   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
1221     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1222     // so x rounded to an integer may or may not fit in a signed 64-bit int
1223     // the cases that do not fit are identified here; the ones that fit
1224     // fall through and will be handled with other cases further,
1225     // under '1 <= q + exp <= 19'
1226     if (x_sign) { // if n < 0 and q + exp = 19
1227       // if n <= -2^63 - 1 then n is too large
1228       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1
1229       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=7
1230       // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=7
1231       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1232       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1233       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1234       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1235 	// set invalid flag
1236 	*pfpsf |= BID_INVALID_EXCEPTION;
1237 	// return Integer Indefinite
1238 	res = 0x8000000000000000ull;
1239 	BID_RETURN (res);
1240       }
1241       // else cases that can be rounded to a 64-bit int fall through
1242       // to '1 <= q + exp <= 19'
1243     } else { // if n > 0 and q + exp = 19
1244       // if n > 2^63 - 1 then n is too large
1245       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] > 2^63 - 1
1246       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=7
1247       // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=7
1248       C.w[1] = 0x0000000000000004ull;
1249       C.w[0] = 0xfffffffffffffff6ull;
1250       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1251       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1252       if (C.w[1] > 0x04ull ||
1253 	  (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
1254 	// set invalid flag
1255 	*pfpsf |= BID_INVALID_EXCEPTION;
1256 	// return Integer Indefinite
1257 	res = 0x8000000000000000ull;
1258 	BID_RETURN (res);
1259       }
1260       // else cases that can be rounded to a 64-bit int fall through
1261       // to '1 <= q + exp <= 19'
1262     }	// end else if n > 0 and q + exp = 19
1263   }	// end else if ((q + exp) == 19)
1264 
1265   // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1266   // Note: some of the cases tested for above fall through to this point
1267   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1268     // set inexact flag
1269     *pfpsf |= BID_INEXACT_EXCEPTION;
1270     // return 0 or 1
1271     if (x_sign)
1272       res = 0x00000000;
1273     else
1274       res = 0x00000001;
1275     BID_RETURN (res);
1276   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
1277     // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1278     // to nearest to a 64-bit signed integer
1279     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
1280       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
1281       // chop off ind digits from the lower part of C1
1282       // C1 fits in 64 bits
1283       // calculate C* and f*
1284       // C* is actually floor(C*) in this case
1285       // C* and f* need shifting and masking, as shown by
1286       // bid_shiftright128[] and bid_maskhigh128[]
1287       // 1 <= x <= 6
1288       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
1289       // C* = C1 * 10^(-x)
1290       // the approximation of 10^(-x) was rounded up to 54 bits
1291       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
1292       Cstar = P128.w[1];
1293       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
1294       fstar.w[0] = P128.w[0];
1295       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
1296       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1297       // C* = floor(C*) (logical right shift; C has p decimal digits,
1298       //     correct by Property 1)
1299       // n = C* * 10^(e+x)
1300 
1301       // shift right C* by Ex-64 = bid_shiftright128[ind]
1302       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1303       Cstar = Cstar >> shift;
1304       // determine inexactness of the rounding of C*
1305       // if (0 < f* < 10^(-x)) then
1306       //   the result is exact
1307       // else // if (f* > T*) then
1308       //   the result is inexact
1309       if (ind - 1 <= 2) { // fstar.w[1] is 0
1310 	if (fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1311 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1312 	  // bid_ten2mk128[ind -1].w[1]
1313 	  if (!x_sign) { // positive and inexact
1314 	    Cstar++;
1315 	  }
1316 	  // set the inexact flag
1317 	  *pfpsf |= BID_INEXACT_EXCEPTION;
1318 	}	// else the result is exact
1319       } else { // if 3 <= ind - 1 <= 14
1320 	if (fstar.w[1] || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1321 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1322 	  // bid_ten2mk128[ind -1].w[1]
1323 	  if (!x_sign) { // positive and inexact
1324 	    Cstar++;
1325 	  }
1326 	  // set the inexact flag
1327 	  *pfpsf |= BID_INEXACT_EXCEPTION;
1328 	}	// else the result is exact
1329       }
1330 
1331       if (x_sign)
1332 	res = -Cstar;
1333       else
1334 	res = Cstar;
1335     } else if (exp == 0) {
1336       // 1 <= q <= 7
1337       // res = +/-C (exact)
1338       if (x_sign)
1339 	res = -(BID_UINT64)C1;
1340       else
1341 	res = C1;
1342     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
1343       // (the upper limit of 20 on q + exp is due to the fact that
1344       // +/-C * 10^exp is guaranteed to fit in 64 bits)
1345       // res = +/-C * 10^exp (exact)
1346       if (x_sign)
1347 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
1348       else
1349 	res = C1 * bid_ten2k64[exp];
1350     }
1351   }
1352   BID_RETURN (res);
1353 }
1354 
1355 /*****************************************************************************
1356  *  BID32_to_int64_int
1357  ****************************************************************************/
1358 
1359 #if DECIMAL_CALL_BY_REFERENCE
1360 void
1361 bid32_to_int64_int (BID_SINT64 * pres, BID_UINT32 * px
1362 		    _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1363   BID_UINT32 x = *px;
1364 #else
1365 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_int, 32)
1366 BID_SINT64
1367 bid32_to_int64_int (BID_UINT32 x
1368 		    _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1369 #endif
1370   BID_SINT64 res;
1371   BID_UINT32 x_sign;
1372   BID_UINT32 x_exp;
1373   int exp; // unbiased exponent
1374   // Note: C1 represents x_significand (BID_UINT32)
1375   BID_UI32FLOAT tmp1;
1376   unsigned int x_nr_bits;
1377   int q, ind, shift;
1378   BID_UINT32 C1;
1379   BID_UINT128 C;
1380   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1381   BID_UINT128 P128;
1382 
1383   // check for NaN or Infinity
1384   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
1385     // set invalid flag
1386     *pfpsf |= BID_INVALID_EXCEPTION;
1387     // return Integer Indefinite
1388     res = 0x8000000000000000ull;
1389     BID_RETURN (res);
1390   }
1391   // unpack x
1392   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
1393   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1394   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
1395     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
1396     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
1397     if (C1 > 9999999) { // non-canonical
1398       x_exp = 0;
1399       C1 = 0;
1400     }
1401   } else {
1402     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
1403     C1 = x & MASK_BINARY_SIG1_32;
1404   }
1405 
1406   // check for zeros (possibly from non-canonical values)
1407   if (C1 == 0x0) {
1408     // x is 0
1409     res = 0x00000000;
1410     BID_RETURN (res);
1411   }
1412   // x is not special and is not zero
1413 
1414   // q = nr. of decimal digits in x (1 <= q <= 7)
1415   //  determine first the nr. of bits in x
1416   tmp1.f = (float) C1; // exact conversion
1417   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
1418   q = bid_nr_digits[x_nr_bits - 1].digits;
1419   if (q == 0) {
1420     q = bid_nr_digits[x_nr_bits - 1].digits1;
1421     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
1422       q++;
1423   }
1424   exp = x_exp - 101; // unbiased exponent
1425 
1426   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
1427     // set invalid flag
1428     *pfpsf |= BID_INVALID_EXCEPTION;
1429     // return Integer Indefinite
1430     res = 0x8000000000000000ull;
1431     BID_RETURN (res);
1432   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
1433     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1434     // so x rounded to an integer may or may not fit in a signed 64-bit int
1435     // the cases that do not fit are identified here; the ones that fit
1436     // fall through and will be handled with other cases further,
1437     // under '1 <= q + exp <= 19'
1438     if (x_sign) { // if n < 0 and q + exp = 19
1439       // if n <= -2^63 - 1 then n is too large
1440       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1
1441       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=7
1442       // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=7
1443       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1444       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1445       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1446       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1447 	// set invalid flag
1448 	*pfpsf |= BID_INVALID_EXCEPTION;
1449 	// return Integer Indefinite
1450 	res = 0x8000000000000000ull;
1451 	BID_RETURN (res);
1452       }
1453       // else cases that can be rounded to a 64-bit int fall through
1454       // to '1 <= q + exp <= 19'
1455     } else { // if n > 0 and q + exp = 19
1456       // if n >= 2^63 then n is too large
1457       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63
1458       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=7
1459       // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=7
1460       C.w[1] = 0x0000000000000005ull;
1461       C.w[0] = 0x0000000000000000ull;
1462       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1463       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1464       if (C.w[1] >= 0x05ull) {
1465 	// actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1466 	// set invalid flag
1467 	*pfpsf |= BID_INVALID_EXCEPTION;
1468 	// return Integer Indefinite
1469 	res = 0x8000000000000000ull;
1470 	BID_RETURN (res);
1471       }
1472       // else cases that can be rounded to a 64-bit int fall through
1473       // to '1 <= q + exp <= 19'
1474     }	// end else if n > 0 and q + exp = 19
1475   }	// end else if ((q + exp) == 19)
1476 
1477   // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1478   // Note: some of the cases tested for above fall through to this point
1479   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1480     // return 0
1481     res = 0x0000000000000000ull;
1482     BID_RETURN (res);
1483   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
1484     // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1485     // to nearest to a 64-bit signed integer
1486     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
1487       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
1488       // chop off ind digits from the lower part of C1
1489       // C1 fits in 64 bits
1490       // calculate C* and f*
1491       // C* is actually floor(C*) in this case
1492       // C* and f* need shifting and masking, as shown by
1493       // bid_shiftright128[] and bid_maskhigh128[]
1494       // 1 <= x <= 6
1495       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
1496       // C* = C1 * 10^(-x)
1497       // the approximation of 10^(-x) was rounded up to 54 bits
1498       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
1499       Cstar = P128.w[1];
1500       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
1501       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1502       // C* = floor(C*) (logical right shift; C has p decimal digits,
1503       //     correct by Property 1)
1504       // n = C* * 10^(e+x)
1505 
1506       // shift right C* by Ex-64 = bid_shiftright128[ind]
1507       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1508       Cstar = Cstar >> shift;
1509 
1510       if (x_sign)
1511 	res = -Cstar;
1512       else
1513 	res = Cstar;
1514     } else if (exp == 0) {
1515       // 1 <= q <= 7
1516       // res = +/-C (exact)
1517       if (x_sign)
1518 	res = -(BID_UINT64)C1;
1519       else
1520 	res = C1;
1521     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
1522       // (the upper limit of 20 on q + exp is due to the fact that
1523       // +/-C * 10^exp is guaranteed to fit in 64 bits)
1524       // res = +/-C * 10^exp (exact)
1525       if (x_sign)
1526 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
1527       else
1528 	res = C1 * bid_ten2k64[exp];
1529     }
1530   }
1531   BID_RETURN (res);
1532 }
1533 
1534 /*****************************************************************************
1535  *  BID32_to_int64_xint
1536  ****************************************************************************/
1537 
1538 #if DECIMAL_CALL_BY_REFERENCE
1539 void
1540 bid32_to_int64_xint (BID_SINT64 * pres, BID_UINT32 * px
1541 		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
1542 {
1543   BID_UINT32 x = *px;
1544 #else
1545 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_xint, 32)
1546 BID_SINT64
1547 bid32_to_int64_xint (BID_UINT32 x
1548 		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
1549 {
1550 #endif
1551   BID_SINT64 res;
1552   BID_UINT32 x_sign;
1553   BID_UINT32 x_exp;
1554   int exp; // unbiased exponent
1555   // Note: C1 represents x_significand (BID_UINT32)
1556   BID_UI32FLOAT tmp1;
1557   unsigned int x_nr_bits;
1558   int q, ind, shift;
1559   BID_UINT32 C1;
1560   BID_UINT128 C;
1561   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1562   BID_UINT128 fstar;
1563   BID_UINT128 P128;
1564 
1565   // check for NaN or Infinity
1566   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
1567     // set invalid flag
1568     *pfpsf |= BID_INVALID_EXCEPTION;
1569     // return Integer Indefinite
1570     res = 0x8000000000000000ull;
1571     BID_RETURN (res);
1572   }
1573   // unpack x
1574   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
1575   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1576   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
1577     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
1578     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
1579     if (C1 > 9999999) { // non-canonical
1580       x_exp = 0;
1581       C1 = 0;
1582     }
1583   } else {
1584     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
1585     C1 = x & MASK_BINARY_SIG1_32;
1586   }
1587 
1588   // check for zeros (possibly from non-canonical values)
1589   if (C1 == 0x0) {
1590     // x is 0
1591     res = 0x00000000;
1592     BID_RETURN (res);
1593   }
1594   // x is not special and is not zero
1595 
1596   // q = nr. of decimal digits in x (1 <= q <= 7)
1597   //  determine first the nr. of bits in x
1598   tmp1.f = (float) C1; // exact conversion
1599   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
1600   q = bid_nr_digits[x_nr_bits - 1].digits;
1601   if (q == 0) {
1602     q = bid_nr_digits[x_nr_bits - 1].digits1;
1603     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
1604       q++;
1605   }
1606   exp = x_exp - 101; // unbiased exponent
1607 
1608   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
1609     // set invalid flag
1610     *pfpsf |= BID_INVALID_EXCEPTION;
1611     // return Integer Indefinite
1612     res = 0x8000000000000000ull;
1613     BID_RETURN (res);
1614   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
1615     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1616     // so x rounded to an integer may or may not fit in a signed 64-bit int
1617     // the cases that do not fit are identified here; the ones that fit
1618     // fall through and will be handled with other cases further,
1619     // under '1 <= q + exp <= 19'
1620     if (x_sign) { // if n < 0 and q + exp = 19
1621       // if n <= -2^63 - 1 then n is too large
1622       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1
1623       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=7
1624       // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=7
1625       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1626       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1627       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1628       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1629 	// set invalid flag
1630 	*pfpsf |= BID_INVALID_EXCEPTION;
1631 	// return Integer Indefinite
1632 	res = 0x8000000000000000ull;
1633 	BID_RETURN (res);
1634       }
1635       // else cases that can be rounded to a 64-bit int fall through
1636       // to '1 <= q + exp <= 19'
1637     } else { // if n > 0 and q + exp = 19
1638       // if n >= 2^63 then n is too large
1639       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63
1640       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=7
1641       // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=7
1642       C.w[1] = 0x0000000000000005ull;
1643       C.w[0] = 0x0000000000000000ull;
1644       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1645       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1646       if (C.w[1] >= 0x05ull) {
1647 	// actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1648 	// set invalid flag
1649 	*pfpsf |= BID_INVALID_EXCEPTION;
1650 	// return Integer Indefinite
1651 	res = 0x8000000000000000ull;
1652 	BID_RETURN (res);
1653       }
1654       // else cases that can be rounded to a 64-bit int fall through
1655       // to '1 <= q + exp <= 19'
1656     }	// end else if n > 0 and q + exp = 19
1657   }	// end else if ((q + exp) == 19)
1658 
1659   // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1660   // Note: some of the cases tested for above fall through to this point
1661   if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1662     // set inexact flag
1663     *pfpsf |= BID_INEXACT_EXCEPTION;
1664     // return 0
1665     res = 0x0000000000000000ull;
1666     BID_RETURN (res);
1667   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
1668     // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1669     // to nearest to a 64-bit signed integer
1670     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
1671       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
1672       // chop off ind digits from the lower part of C1
1673       // C1 fits in 64 bits
1674       // calculate C* and f*
1675       // C* is actually floor(C*) in this case
1676       // C* and f* need shifting and masking, as shown by
1677       // bid_shiftright128[] and bid_maskhigh128[]
1678       // 1 <= x <= 6
1679       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
1680       // C* = C1 * 10^(-x)
1681       // the approximation of 10^(-x) was rounded up to 54 bits
1682       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
1683       Cstar = P128.w[1];
1684       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
1685       fstar.w[0] = P128.w[0];
1686       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
1687       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1688       // C* = floor(C*) (logical right shift; C has p decimal digits,
1689       //     correct by Property 1)
1690       // n = C* * 10^(e+x)
1691 
1692       // shift right C* by Ex-64 = bid_shiftright128[ind]
1693       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1694       Cstar = Cstar >> shift;
1695       // determine inexactness of the rounding of C*
1696       // if (0 < f* < 10^(-x)) then
1697       //   the result is exact
1698       // else // if (f* > T*) then
1699       //   the result is inexact
1700       if (ind - 1 <= 2) { // fstar.w[1] is 0
1701 	if (fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1702 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1703 	  // bid_ten2mk128[ind -1].w[1]
1704 	  // set the inexact flag
1705 	  *pfpsf |= BID_INEXACT_EXCEPTION;
1706 	}	// else the result is exact
1707       } else { // if 3 <= ind - 1 <= 14
1708 	if (fstar.w[1] || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
1709 	  // bid_ten2mk128trunc[ind -1].w[1] is identical to
1710 	  // bid_ten2mk128[ind -1].w[1]
1711 	  // set the inexact flag
1712 	  *pfpsf |= BID_INEXACT_EXCEPTION;
1713 	}	// else the result is exact
1714       }
1715       if (x_sign)
1716 	res = -Cstar;
1717       else
1718 	res = Cstar;
1719     } else if (exp == 0) {
1720       // 1 <= q <= 7
1721       // res = +/-C (exact)
1722       if (x_sign)
1723 	res = -(BID_UINT64)C1;
1724       else
1725 	res = C1;
1726     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
1727       // (the upper limit of 20 on q + exp is due to the fact that
1728       // +/-C * 10^exp is guaranteed to fit in 64 bits)
1729       // res = +/-C * 10^exp (exact)
1730       if (x_sign)
1731 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
1732       else
1733 	res = C1 * bid_ten2k64[exp];
1734     }
1735   }
1736   BID_RETURN (res);
1737 }
1738 
1739 /*****************************************************************************
1740  *  BID32_to_int64_rninta
1741  ****************************************************************************/
1742 
1743 #if DECIMAL_CALL_BY_REFERENCE
1744 void
1745 bid32_to_int64_rninta (BID_SINT64 * pres, BID_UINT32 * px
1746 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1747 		       _EXC_INFO_PARAM) {
1748   BID_UINT32 x = *px;
1749 #else
1750 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_rninta, 32)
1751 BID_SINT64
1752 bid32_to_int64_rninta (BID_UINT32 x
1753 		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1754 		       _EXC_INFO_PARAM) {
1755 #endif
1756   BID_SINT64 res;
1757   BID_UINT32 x_sign;
1758   BID_UINT32 x_exp;
1759   int exp; // unbiased exponent
1760   // Note: C1 represents x_significand (BID_UINT32)
1761   BID_UI32FLOAT tmp1;
1762   unsigned int x_nr_bits;
1763   int q, ind, shift;
1764   BID_UINT32 C1;
1765   BID_UINT128 C;
1766   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1767   BID_UINT128 P128;
1768 
1769   // check for NaN or Infinity
1770   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
1771     // set invalid flag
1772     *pfpsf |= BID_INVALID_EXCEPTION;
1773     // return Integer Indefinite
1774     res = 0x8000000000000000ull;
1775     BID_RETURN (res);
1776   }
1777   // unpack x
1778   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
1779   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1780   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
1781     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
1782     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
1783     if (C1 > 9999999) { // non-canonical
1784       x_exp = 0;
1785       C1 = 0;
1786     }
1787   } else {
1788     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
1789     C1 = x & MASK_BINARY_SIG1_32;
1790   }
1791 
1792   // check for zeros (possibly from non-canonical values)
1793   if (C1 == 0x0) {
1794     // x is 0
1795     res = 0x00000000;
1796     BID_RETURN (res);
1797   }
1798   // x is not special and is not zero
1799 
1800   // q = nr. of decimal digits in x (1 <= q <= 7)
1801   //  determine first the nr. of bits in x
1802   tmp1.f = (float) C1; // exact conversion
1803   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
1804   q = bid_nr_digits[x_nr_bits - 1].digits;
1805   if (q == 0) {
1806     q = bid_nr_digits[x_nr_bits - 1].digits1;
1807     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
1808       q++;
1809   }
1810   exp = x_exp - 101; // unbiased exponent
1811 
1812   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
1813     // set invalid flag
1814     *pfpsf |= BID_INVALID_EXCEPTION;
1815     // return Integer Indefinite
1816     res = 0x8000000000000000ull;
1817     BID_RETURN (res);
1818   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
1819     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1820     // so x rounded to an integer may or may not fit in a signed 64-bit int
1821     // the cases that do not fit are identified here; the ones that fit
1822     // fall through and will be handled with other cases further,
1823     // under '1 <= q + exp <= 19'
1824     if (x_sign) { // if n < 0 and q + exp = 19
1825       // if n <= -2^63 - 1/2 then n is too large
1826       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1/2
1827       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=7
1828       // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=7
1829       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1830       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1831       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
1832       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
1833 	// set invalid flag
1834 	*pfpsf |= BID_INVALID_EXCEPTION;
1835 	// return Integer Indefinite
1836 	res = 0x8000000000000000ull;
1837 	BID_RETURN (res);
1838       }
1839       // else cases that can be rounded to a 64-bit int fall through
1840       // to '1 <= q + exp <= 19'
1841     } else { // if n > 0 and q + exp = 19
1842       // if n >= 2^63 - 1/2 then n is too large
1843       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63-1/2
1844       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=7
1845       // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=7
1846       C.w[1] = 0x0000000000000004ull;
1847       C.w[0] = 0xfffffffffffffffbull;
1848       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1849       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
1850       if (C.w[1] > 0x04ull ||
1851 	  (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
1852 	// set invalid flag
1853 	*pfpsf |= BID_INVALID_EXCEPTION;
1854 	// return Integer Indefinite
1855 	res = 0x8000000000000000ull;
1856 	BID_RETURN (res);
1857       }
1858       // else cases that can be rounded to a 64-bit int fall through
1859       // to '1 <= q + exp <= 19'
1860     }	// end else if n > 0 and q + exp = 19
1861   }	// end else if ((q + exp) == 19)
1862 
1863   // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
1864   // Note: some of the cases tested for above fall through to this point
1865   if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1866     // return 0
1867     res = 0x0000000000000000ull;
1868     BID_RETURN (res);
1869   } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
1870     // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
1871     //   res = 0
1872     // else
1873     //   res = +/-1
1874     ind = q - 1; // 0 <= ind <= 6
1875     if (C1 < bid_midpoint64[ind]) {
1876       res = 0x0000000000000000ull; // return 0
1877     } else if (x_sign) { // n < 0
1878       res = 0xffffffffffffffffull; // return -1
1879     } else { // n > 0
1880       res = 0x0000000000000001ull; // return +1
1881     }
1882   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
1883     // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
1884     // to nearest to a 64-bit signed integer
1885     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
1886       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
1887       // chop off ind digits from the lower part of C1
1888       // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
1889       C1 = C1 + (BID_UINT32)bid_midpoint64[ind - 1];
1890       // calculate C* and f*
1891       // C* is actually floor(C*) in this case
1892       // C* and f* need shifting and masking, as shown by
1893       // bid_shiftright128[] and bid_maskhigh128[]
1894       // 1 <= x <= 6
1895       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
1896       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
1897       // the approximation of 10^(-x) was rounded up to 54 bits
1898       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
1899       Cstar = P128.w[1];
1900       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
1901       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1902       // if (0 < f* < 10^(-x)) then the result is a midpoint
1903       //   if floor(C*) is even then C* = floor(C*) - logical right
1904       //       shift; C* has p decimal digits, correct by Prop. 1)
1905       //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
1906       //       shift; C* has p decimal digits, correct by Pr. 1)
1907       // else
1908       //   C* = floor(C*) (logical right shift; C has p decimal digits,
1909       //       correct by Property 1)
1910       // n = C* * 10^(e+x)
1911 
1912       // shift right C* by Ex-64 = bid_shiftright128[ind]
1913       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1914       Cstar = Cstar >> shift;
1915 
1916       // if the result was a midpoint it was rounded away from zero
1917       if (x_sign)
1918 	res = -Cstar;
1919       else
1920 	res = Cstar;
1921     } else if (exp == 0) {
1922       // 1 <= q <= 7
1923       // res = +/-C (exact)
1924       if (x_sign)
1925 	res = -(BID_UINT64)C1;
1926       else
1927 	res = C1;
1928     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
1929       // (the upper limit of 20 on q + exp is due to the fact that
1930       // +/-C * 10^exp is guaranteed to fit in 64 bits)
1931       // res = +/-C * 10^exp (exact)
1932       if (x_sign)
1933 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
1934       else
1935 	res = C1 * bid_ten2k64[exp];
1936     }
1937   }
1938   BID_RETURN (res);
1939 }
1940 
1941 /*****************************************************************************
1942  *  BID32_to_int64_xrninta
1943  ****************************************************************************/
1944 
1945 #if DECIMAL_CALL_BY_REFERENCE
1946 void
1947 bid32_to_int64_xrninta (BID_SINT64 * pres, BID_UINT32 * px
1948 			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1949 			_EXC_INFO_PARAM) {
1950   BID_UINT32 x = *px;
1951 #else
1952 RES_WRAPFN_DFP(BID_SINT64, bid32_to_int64_xrninta, 32)
1953 BID_SINT64
1954 bid32_to_int64_xrninta (BID_UINT32 x
1955 			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1956 			_EXC_INFO_PARAM) {
1957 #endif
1958   BID_SINT64 res;
1959   BID_UINT32 x_sign;
1960   BID_UINT32 x_exp;
1961   int exp; // unbiased exponent
1962   // Note: C1 represents x_significand (BID_UINT32)
1963   BID_UINT64 tmp64;
1964   BID_UI32FLOAT tmp1;
1965   unsigned int x_nr_bits;
1966   int q, ind, shift;
1967   BID_UINT32 C1;
1968   BID_UINT128 C;
1969   BID_UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1970   BID_UINT128 fstar;
1971   BID_UINT128 P128;
1972 
1973   // check for NaN or Infinity
1974   if ((x & MASK_NAN32) == MASK_NAN32 || (x & MASK_INF32) == MASK_INF32) {
1975     // set invalid flag
1976     *pfpsf |= BID_INVALID_EXCEPTION;
1977     // return Integer Indefinite
1978     res = 0x8000000000000000ull;
1979     BID_RETURN (res);
1980   }
1981   // unpack x
1982   x_sign = x & MASK_SIGN32; // 0 for positive, MASK_SIGN32 for negative
1983   // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1984   if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) {
1985     x_exp = (x & MASK_BINARY_EXPONENT2_32) >> 21; // biased
1986     C1 = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32;
1987     if (C1 > 9999999) { // non-canonical
1988       x_exp = 0;
1989       C1 = 0;
1990     }
1991   } else {
1992     x_exp = (x & MASK_BINARY_EXPONENT1_32) >> 23; // biased
1993     C1 = x & MASK_BINARY_SIG1_32;
1994   }
1995 
1996   // check for zeros (possibly from non-canonical values)
1997   if (C1 == 0x0) {
1998     // x is 0
1999     res = 0x00000000;
2000     BID_RETURN (res);
2001   }
2002   // x is not special and is not zero
2003 
2004   // q = nr. of decimal digits in x (1 <= q <= 7)
2005   //  determine first the nr. of bits in x
2006   tmp1.f = (float) C1; // exact conversion
2007   x_nr_bits = 1 + ((tmp1.ui32 >> 23) & 0xff) - 0x7f;
2008   q = bid_nr_digits[x_nr_bits - 1].digits;
2009   if (q == 0) {
2010     q = bid_nr_digits[x_nr_bits - 1].digits1;
2011     if (C1 >= bid_nr_digits[x_nr_bits - 1].threshold_lo)
2012       q++;
2013   }
2014   exp = x_exp - 101; // unbiased exponent
2015 
2016   if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in BID_SINT64)
2017     // set invalid flag
2018     *pfpsf |= BID_INVALID_EXCEPTION;
2019     // return Integer Indefinite
2020     res = 0x8000000000000000ull;
2021     BID_RETURN (res);
2022   } else if ((q + exp) == 19) { // x = c(0)c(1)...c(q-1)00...0 (19 dec. digits)
2023     // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2024     // so x rounded to an integer may or may not fit in a signed 64-bit int
2025     // the cases that do not fit are identified here; the ones that fit
2026     // fall through and will be handled with other cases further,
2027     // under '1 <= q + exp <= 19'
2028     if (x_sign) { // if n < 0 and q + exp = 19
2029       // if n <= -2^63 - 1/2 then n is too large
2030       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63+1/2
2031       // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=7
2032       // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=7
2033       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2034       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
2035       // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
2036       if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
2037 	// set invalid flag
2038 	*pfpsf |= BID_INVALID_EXCEPTION;
2039 	// return Integer Indefinite
2040 	res = 0x8000000000000000ull;
2041 	BID_RETURN (res);
2042       }
2043       // else cases that can be rounded to a 64-bit int fall through
2044       // to '1 <= q + exp <= 19'
2045     } else { // if n > 0 and q + exp = 19
2046       // if n >= 2^63 - 1/2 then n is too large
2047       // <=> c(0)c(1)...c(q-1)00...0[19 dec. digits] >= 2^63-1/2
2048       // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=7
2049       // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=7
2050       C.w[1] = 0x0000000000000004ull;
2051       C.w[0] = 0xfffffffffffffffbull;
2052       // 1 <= q <= 7 => 13 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2053       __mul_64x64_to_128MACH (C, (BID_UINT64)C1, bid_ten2k64[20 - q]);
2054       if (C.w[1] > 0x04ull ||
2055 	  (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
2056 	// set invalid flag
2057 	*pfpsf |= BID_INVALID_EXCEPTION;
2058 	// return Integer Indefinite
2059 	res = 0x8000000000000000ull;
2060 	BID_RETURN (res);
2061       }
2062       // else cases that can be rounded to a 64-bit int fall through
2063       // to '1 <= q + exp <= 19'
2064     }	// end else if n > 0 and q + exp = 19
2065   }	// end else if ((q + exp) == 19)
2066 
2067   // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
2068   // Note: some of the cases tested for above fall through to this point
2069   if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2070     // set inexact flag
2071     *pfpsf |= BID_INEXACT_EXCEPTION;
2072     // return 0
2073     res = 0x0000000000000000ull;
2074     BID_RETURN (res);
2075   } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2076     // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
2077     //   res = 0
2078     // else
2079     //   res = +/-1
2080     ind = q - 1; // 0 <= ind <= 6
2081     if (C1 < bid_midpoint64[ind]) {
2082       res = 0x0000000000000000ull; // return 0
2083     } else if (x_sign) { // n < 0
2084       res = 0xffffffffffffffffull; // return -1
2085     } else { // n > 0
2086       res = 0x0000000000000001ull; // return +1
2087     }
2088     // set inexact flag
2089     *pfpsf |= BID_INEXACT_EXCEPTION;
2090   } else { // if (1 <= q + exp <= 19, 1 <= q <= 7, -6 <= exp <= 18)
2091     // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2092     // to nearest to a 64-bit signed integer
2093     if (exp < 0) { // 2 <= q <= 7, -6 <= exp <= -1, 1 <= q + exp <= 19
2094       ind = -exp; // 1 <= ind <= 6; ind is a synonym for 'x'
2095       // chop off ind digits from the lower part of C1
2096       // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
2097       C1 = C1 + (BID_UINT32)bid_midpoint64[ind - 1];
2098       // calculate C* and f*
2099       // C* is actually floor(C*) in this case
2100       // C* and f* need shifting and masking, as shown by
2101       // bid_shiftright128[] and bid_maskhigh128[]
2102       // 1 <= x <= 6
2103       // kx = 10^(-x) = bid_ten2mk64[ind - 1]
2104       // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2105       // the approximation of 10^(-x) was rounded up to 54 bits
2106       __mul_64x64_to_128MACH (P128, (BID_UINT64)C1, bid_ten2mk64[ind - 1]);
2107       Cstar = P128.w[1];
2108       fstar.w[1] = P128.w[1] & bid_maskhigh128[ind - 1];
2109       fstar.w[0] = P128.w[0];
2110       // the top Ex bits of 10^(-x) are T* = bid_ten2mk128trunc[ind].w[0], e.g.
2111       // if x=1, T*=bid_ten2mk128trunc[0].w[0]=0x1999999999999999
2112       // if (0 < f* < 10^(-x)) then the result is a midpoint
2113       //   if floor(C*) is even then C* = floor(C*) - logical right
2114       //       shift; C* has p decimal digits, correct by Prop. 1)
2115       //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
2116       //       shift; C* has p decimal digits, correct by Pr. 1)
2117       // else
2118       //   C* = floor(C*) (logical right shift; C has p decimal digits,
2119       //       correct by Property 1)
2120       // n = C* * 10^(e+x)
2121 
2122       // shift right C* by Ex-64 = bid_shiftright128[ind]
2123       shift = bid_shiftright128[ind - 1]; // 0 <= shift <= 39
2124       Cstar = Cstar >> shift;
2125       // determine inexactness of the rounding of C*
2126       // if (0 < f* - 1/2 < 10^(-x)) then
2127       //   the result is exact
2128       // else // if (f* - 1/2 > T*) then
2129       //   the result is inexact
2130       if (ind - 1 <= 2) {
2131 	if (fstar.w[0] > 0x8000000000000000ull) {
2132 	  // f* > 1/2 and the result may be exact
2133 	  tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
2134 	  if ((tmp64 > bid_ten2mk128trunc[ind - 1].w[1])) {
2135 	    // bid_ten2mk128trunc[ind -1].w[1] is identical to
2136 	    // bid_ten2mk128[ind -1].w[1]
2137 	    // set the inexact flag
2138 	    *pfpsf |= BID_INEXACT_EXCEPTION;
2139 	  }	// else the result is exact
2140 	} else { // the result is inexact; f2* <= 1/2
2141 	  // set the inexact flag
2142 	  *pfpsf |= BID_INEXACT_EXCEPTION;
2143 	}
2144       } else { // if 3 <= ind - 1 <= 14
2145 	if (fstar.w[1] > bid_onehalf128[ind - 1] ||
2146 	    (fstar.w[1] == bid_onehalf128[ind - 1] && fstar.w[0])) {
2147 	  // f2* > 1/2 and the result may be exact
2148 	  // Calculate f2* - 1/2
2149 	  tmp64 = fstar.w[1] - bid_onehalf128[ind - 1];
2150 	  if (tmp64 || fstar.w[0] > bid_ten2mk128trunc[ind - 1].w[1]) {
2151 	    // bid_ten2mk128trunc[ind -1].w[1] is identical to
2152 	    // bid_ten2mk128[ind -1].w[1]
2153 	    // set the inexact flag
2154 	    *pfpsf |= BID_INEXACT_EXCEPTION;
2155 	  }	// else the result is exact
2156 	} else { // the result is inexact; f2* <= 1/2
2157 	  // set the inexact flag
2158 	  *pfpsf |= BID_INEXACT_EXCEPTION;
2159 	}
2160       }
2161 
2162       // if the result was a midpoint it was rounded away from zero
2163       if (x_sign)
2164 	res = -Cstar;
2165       else
2166 	res = Cstar;
2167     } else if (exp == 0) {
2168       // 1 <= q <= 7
2169       // res = +/-C (exact)
2170       if (x_sign)
2171 	res = -(BID_UINT64)C1;
2172       else
2173 	res = C1;
2174     } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 7, 2 <= q + exp <= 20
2175       // (the upper limit of 20 on q + exp is due to the fact that
2176       // +/-C * 10^exp is guaranteed to fit in 64 bits)
2177       // res = +/-C * 10^exp (exact)
2178       if (x_sign)
2179 	res = -(BID_UINT64)C1 * bid_ten2k64[exp];
2180       else
2181 	res = C1 * bid_ten2k64[exp];
2182     }
2183   }
2184   BID_RETURN (res);
2185 }
2186