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