comparison libgcc/config/libbid/bid64_to_uint32.c @ 0:a06113de4d67

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