c++: reduce unnecessary tree_common
[official-gcc.git] / libgcc / config / libbid / bid128_to_uint64.c
bloba0d9c227cf0a282651808567348480e142f1c07a
1 /* Copyright (C) 2007-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
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.
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.
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.
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/>. */
24 #include "bid_internal.h"
26 /*****************************************************************************
27 * BID128_to_uint64_rnint
28 ****************************************************************************/
30 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
31 bid128_to_uint64_rnint, x)
33 UINT64 res;
34 UINT64 x_sign;
35 UINT64 x_exp;
36 int exp; // unbiased exponent
37 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
38 UINT64 tmp64;
39 BID_UI64DOUBLE tmp1;
40 unsigned int x_nr_bits;
41 int q, ind, shift;
42 UINT128 C1, C;
43 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
44 UINT256 fstar;
45 UINT256 P256;
47 // unpack x
48 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
49 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
50 C1.w[1] = x.w[1] & MASK_COEFF;
51 C1.w[0] = x.w[0];
53 // check for NaN or Infinity
54 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
55 // x is special
56 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
57 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
58 // set invalid flag
59 *pfpsf |= INVALID_EXCEPTION;
60 // return Integer Indefinite
61 res = 0x8000000000000000ull;
62 } else { // x is QNaN
63 // set invalid flag
64 *pfpsf |= INVALID_EXCEPTION;
65 // return Integer Indefinite
66 res = 0x8000000000000000ull;
68 BID_RETURN (res);
69 } else { // x is not a NaN, so it must be infinity
70 if (!x_sign) { // x is +inf
71 // set invalid flag
72 *pfpsf |= INVALID_EXCEPTION;
73 // return Integer Indefinite
74 res = 0x8000000000000000ull;
75 } else { // x is -inf
76 // set invalid flag
77 *pfpsf |= INVALID_EXCEPTION;
78 // return Integer Indefinite
79 res = 0x8000000000000000ull;
81 BID_RETURN (res);
84 // check for non-canonical values (after the check for special values)
85 if ((C1.w[1] > 0x0001ed09bead87c0ull)
86 || (C1.w[1] == 0x0001ed09bead87c0ull
87 && (C1.w[0] > 0x378d8e63ffffffffull))
88 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
89 res = 0x0000000000000000ull;
90 BID_RETURN (res);
91 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
92 // x is 0
93 res = 0x0000000000000000ull;
94 BID_RETURN (res);
95 } else { // x is not special and is not zero
97 // q = nr. of decimal digits in x
98 // determine first the nr. of bits in x
99 if (C1.w[1] == 0) {
100 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
101 // split the 64-bit value in two 32-bit halves to avoid rounding errors
102 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
103 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
104 x_nr_bits =
105 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
106 } else { // x < 2^32
107 tmp1.d = (double) (C1.w[0]); // exact conversion
108 x_nr_bits =
109 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
111 } else { // if x < 2^53
112 tmp1.d = (double) C1.w[0]; // exact conversion
113 x_nr_bits =
114 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
116 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
117 tmp1.d = (double) C1.w[1]; // exact conversion
118 x_nr_bits =
119 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
121 q = nr_digits[x_nr_bits - 1].digits;
122 if (q == 0) {
123 q = nr_digits[x_nr_bits - 1].digits1;
124 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
125 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
126 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
127 q++;
129 exp = (x_exp >> 49) - 6176;
131 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
132 // set invalid flag
133 *pfpsf |= INVALID_EXCEPTION;
134 // return Integer Indefinite
135 res = 0x8000000000000000ull;
136 BID_RETURN (res);
137 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
138 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
139 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
140 // the cases that do not fit are identified here; the ones that fit
141 // fall through and will be handled with other cases further,
142 // under '1 <= q + exp <= 20'
143 if (x_sign) { // if n < 0 and q + exp = 20
144 // if n < -1/2 then n cannot be converted to uint64 with RN
145 // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 1/2
146 // <=> 0.c(0)c(1)...c(q-1) * 10^21 > 0x05, 1<=q<=34
147 // <=> C * 10^(21-q) > 0x05, 1<=q<=34
148 if (q == 21) {
149 // C > 5
150 if (C1.w[1] != 0 || C1.w[0] > 0x05ull) {
151 // set invalid flag
152 *pfpsf |= INVALID_EXCEPTION;
153 // return Integer Indefinite
154 res = 0x8000000000000000ull;
155 BID_RETURN (res);
157 // else cases that can be rounded to 64-bit unsigned int fall through
158 // to '1 <= q + exp <= 20'
159 } else {
160 // if 1 <= q <= 20
161 // C * 10^(21-q) > 5 is true because C >= 1 and 10^(21-q) >= 10
162 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
163 // C > 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
164 // set invalid flag
165 *pfpsf |= INVALID_EXCEPTION;
166 // return Integer Indefinite
167 res = 0x8000000000000000ull;
168 BID_RETURN (res);
170 } else { // if n > 0 and q + exp = 20
171 // if n >= 2^64 - 1/2 then n is too large
172 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
173 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
174 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
175 // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
176 if (q == 1) {
177 // C * 10^20 >= 0x9fffffffffffffffb
178 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
179 if (C.w[1] > 0x09 || (C.w[1] == 0x09
180 && C.w[0] >= 0xfffffffffffffffbull)) {
181 // set invalid flag
182 *pfpsf |= INVALID_EXCEPTION;
183 // return Integer Indefinite
184 res = 0x8000000000000000ull;
185 BID_RETURN (res);
187 // else cases that can be rounded to a 64-bit int fall through
188 // to '1 <= q + exp <= 20'
189 } else if (q <= 19) {
190 // C * 10^(21-q) >= 0x9fffffffffffffffb
191 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
192 if (C.w[1] > 0x09 || (C.w[1] == 0x09
193 && C.w[0] >= 0xfffffffffffffffbull)) {
194 // set invalid flag
195 *pfpsf |= INVALID_EXCEPTION;
196 // return Integer Indefinite
197 res = 0x8000000000000000ull;
198 BID_RETURN (res);
200 // else cases that can be rounded to a 64-bit int fall through
201 // to '1 <= q + exp <= 20'
202 } else if (q == 20) {
203 // C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
204 C.w[0] = C1.w[0] + C1.w[0];
205 C.w[1] = C1.w[1] + C1.w[1];
206 if (C.w[0] < C1.w[0])
207 C.w[1]++;
208 if (C.w[1] > 0x01 || (C.w[1] == 0x01
209 && C.w[0] >= 0xffffffffffffffffull)) {
210 // set invalid flag
211 *pfpsf |= INVALID_EXCEPTION;
212 // return Integer Indefinite
213 res = 0x8000000000000000ull;
214 BID_RETURN (res);
216 // else cases that can be rounded to a 64-bit int fall through
217 // to '1 <= q + exp <= 20'
218 } else if (q == 21) {
219 // C >= 0x9fffffffffffffffb
220 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
221 && C1.w[0] >= 0xfffffffffffffffbull)) {
222 // set invalid flag
223 *pfpsf |= INVALID_EXCEPTION;
224 // return Integer Indefinite
225 res = 0x8000000000000000ull;
226 BID_RETURN (res);
228 // else cases that can be rounded to a 64-bit int fall through
229 // to '1 <= q + exp <= 20'
230 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
231 // C >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
232 C.w[1] = 0x09;
233 C.w[0] = 0xfffffffffffffffbull;
234 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
235 if (C1.w[1] > C.w[1]
236 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
237 // set invalid flag
238 *pfpsf |= INVALID_EXCEPTION;
239 // return Integer Indefinite
240 res = 0x8000000000000000ull;
241 BID_RETURN (res);
243 // else cases that can be rounded to a 64-bit int fall through
244 // to '1 <= q + exp <= 20'
248 // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
249 // Note: some of the cases tested for above fall through to this point
250 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
251 // return 0
252 res = 0x0000000000000000ull;
253 BID_RETURN (res);
254 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
255 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
256 // res = 0
257 // else if x > 0
258 // res = +1
259 // else // if x < 0
260 // invalid exc
261 ind = q - 1;
262 if (ind <= 18) { // 0 <= ind <= 18
263 if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) {
264 res = 0x0000000000000000ull; // return 0
265 } else if (!x_sign) { // n > 0
266 res = 0x00000001; // return +1
267 } else {
268 res = 0x8000000000000000ull;
269 *pfpsf |= INVALID_EXCEPTION;
271 } else { // 19 <= ind <= 33
272 if ((C1.w[1] < midpoint128[ind - 19].w[1])
273 || ((C1.w[1] == midpoint128[ind - 19].w[1])
274 && (C1.w[0] <= midpoint128[ind - 19].w[0]))) {
275 res = 0x0000000000000000ull; // return 0
276 } else if (!x_sign) { // n > 0
277 res = 0x00000001; // return +1
278 } else {
279 res = 0x8000000000000000ull;
280 *pfpsf |= INVALID_EXCEPTION;
283 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
284 // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
285 // to nearest to a 64-bit unsigned signed integer
286 if (x_sign) { // x <= -1
287 // set invalid flag
288 *pfpsf |= INVALID_EXCEPTION;
289 // return Integer Indefinite
290 res = 0x8000000000000000ull;
291 BID_RETURN (res);
293 // 1 <= x < 2^64-1/2 so x can be rounded
294 // to nearest to a 64-bit unsigned integer
295 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
296 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
297 // chop off ind digits from the lower part of C1
298 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
299 tmp64 = C1.w[0];
300 if (ind <= 19) {
301 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
302 } else {
303 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
304 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
306 if (C1.w[0] < tmp64)
307 C1.w[1]++;
308 // calculate C* and f*
309 // C* is actually floor(C*) in this case
310 // C* and f* need shifting and masking, as shown by
311 // shiftright128[] and maskhigh128[]
312 // 1 <= x <= 33
313 // kx = 10^(-x) = ten2mk128[ind - 1]
314 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
315 // the approximation of 10^(-x) was rounded up to 118 bits
316 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
317 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
318 Cstar.w[1] = P256.w[3];
319 Cstar.w[0] = P256.w[2];
320 fstar.w[3] = 0;
321 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
322 fstar.w[1] = P256.w[1];
323 fstar.w[0] = P256.w[0];
324 } else { // 22 <= ind - 1 <= 33
325 Cstar.w[1] = 0;
326 Cstar.w[0] = P256.w[3];
327 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
328 fstar.w[2] = P256.w[2];
329 fstar.w[1] = P256.w[1];
330 fstar.w[0] = P256.w[0];
332 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
333 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
334 // if (0 < f* < 10^(-x)) then the result is a midpoint
335 // if floor(C*) is even then C* = floor(C*) - logical right
336 // shift; C* has p decimal digits, correct by Prop. 1)
337 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
338 // shift; C* has p decimal digits, correct by Pr. 1)
339 // else
340 // C* = floor(C*) (logical right shift; C has p decimal digits,
341 // correct by Property 1)
342 // n = C* * 10^(e+x)
344 // shift right C* by Ex-128 = shiftright128[ind]
345 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
346 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
347 Cstar.w[0] =
348 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
349 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
350 } else { // 22 <= ind - 1 <= 33
351 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
353 // if the result was a midpoint it was rounded away from zero, so
354 // it will need a correction
355 // check for midpoints
356 if ((fstar.w[3] == 0) && (fstar.w[2] == 0)
357 && (fstar.w[1] || fstar.w[0])
358 && (fstar.w[1] < ten2mk128trunc[ind - 1].w[1]
359 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
360 && fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) {
361 // the result is a midpoint; round to nearest
362 if (Cstar.w[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
363 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
364 Cstar.w[0]--; // Cstar.w[0] is now even
365 } // else MP in [ODD, EVEN]
367 res = Cstar.w[0]; // the result is positive
368 } else if (exp == 0) {
369 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
370 // res = C (exact)
371 res = C1.w[0];
372 } else {
373 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
374 // res = C * 10^exp (exact) - must fit in 64 bits
375 res = C1.w[0] * ten2k64[exp];
380 BID_RETURN (res);
383 /*****************************************************************************
384 * BID128_to_uint64_xrnint
385 ****************************************************************************/
387 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
388 bid128_to_uint64_xrnint, x)
390 UINT64 res;
391 UINT64 x_sign;
392 UINT64 x_exp;
393 int exp; // unbiased exponent
394 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
395 UINT64 tmp64, tmp64A;
396 BID_UI64DOUBLE tmp1;
397 unsigned int x_nr_bits;
398 int q, ind, shift;
399 UINT128 C1, C;
400 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
401 UINT256 fstar;
402 UINT256 P256;
404 // unpack x
405 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
406 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
407 C1.w[1] = x.w[1] & MASK_COEFF;
408 C1.w[0] = x.w[0];
410 // check for NaN or Infinity
411 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
412 // x is special
413 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
414 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
415 // set invalid flag
416 *pfpsf |= INVALID_EXCEPTION;
417 // return Integer Indefinite
418 res = 0x8000000000000000ull;
419 } else { // x is QNaN
420 // set invalid flag
421 *pfpsf |= INVALID_EXCEPTION;
422 // return Integer Indefinite
423 res = 0x8000000000000000ull;
425 BID_RETURN (res);
426 } else { // x is not a NaN, so it must be infinity
427 if (!x_sign) { // x is +inf
428 // set invalid flag
429 *pfpsf |= INVALID_EXCEPTION;
430 // return Integer Indefinite
431 res = 0x8000000000000000ull;
432 } else { // x is -inf
433 // set invalid flag
434 *pfpsf |= INVALID_EXCEPTION;
435 // return Integer Indefinite
436 res = 0x8000000000000000ull;
438 BID_RETURN (res);
441 // check for non-canonical values (after the check for special values)
442 if ((C1.w[1] > 0x0001ed09bead87c0ull)
443 || (C1.w[1] == 0x0001ed09bead87c0ull
444 && (C1.w[0] > 0x378d8e63ffffffffull))
445 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
446 res = 0x0000000000000000ull;
447 BID_RETURN (res);
448 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
449 // x is 0
450 res = 0x0000000000000000ull;
451 BID_RETURN (res);
452 } else { // x is not special and is not zero
454 // q = nr. of decimal digits in x
455 // determine first the nr. of bits in x
456 if (C1.w[1] == 0) {
457 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
458 // split the 64-bit value in two 32-bit halves to avoid rounding errors
459 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
460 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
461 x_nr_bits =
462 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
463 } else { // x < 2^32
464 tmp1.d = (double) (C1.w[0]); // exact conversion
465 x_nr_bits =
466 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
468 } else { // if x < 2^53
469 tmp1.d = (double) C1.w[0]; // exact conversion
470 x_nr_bits =
471 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
473 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
474 tmp1.d = (double) C1.w[1]; // exact conversion
475 x_nr_bits =
476 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
478 q = nr_digits[x_nr_bits - 1].digits;
479 if (q == 0) {
480 q = nr_digits[x_nr_bits - 1].digits1;
481 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
482 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
483 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
484 q++;
486 exp = (x_exp >> 49) - 6176;
488 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
489 // set invalid flag
490 *pfpsf |= INVALID_EXCEPTION;
491 // return Integer Indefinite
492 res = 0x8000000000000000ull;
493 BID_RETURN (res);
494 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
495 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
496 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
497 // the cases that do not fit are identified here; the ones that fit
498 // fall through and will be handled with other cases further,
499 // under '1 <= q + exp <= 20'
500 if (x_sign) { // if n < 0 and q + exp = 20
501 // if n < -1/2 then n cannot be converted to uint64 with RN
502 // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 1/2
503 // <=> 0.c(0)c(1)...c(q-1) * 10^21 > 0x05, 1<=q<=34
504 // <=> C * 10^(21-q) > 0x05, 1<=q<=34
505 if (q == 21) {
506 // C > 5
507 if (C1.w[1] != 0 || C1.w[0] > 0x05ull) {
508 // set invalid flag
509 *pfpsf |= INVALID_EXCEPTION;
510 // return Integer Indefinite
511 res = 0x8000000000000000ull;
512 BID_RETURN (res);
514 // else cases that can be rounded to 64-bit unsigned int fall through
515 // to '1 <= q + exp <= 20'
516 } else {
517 // if 1 <= q <= 20
518 // C * 10^(21-q) > 5 is true because C >= 1 and 10^(21-q) >= 10
519 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
520 // C > 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
521 // set invalid flag
522 *pfpsf |= INVALID_EXCEPTION;
523 // return Integer Indefinite
524 res = 0x8000000000000000ull;
525 BID_RETURN (res);
527 } else { // if n > 0 and q + exp = 20
528 // if n >= 2^64 - 1/2 then n is too large
529 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
530 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
531 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
532 // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
533 if (q == 1) {
534 // C * 10^20 >= 0x9fffffffffffffffb
535 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
536 if (C.w[1] > 0x09 || (C.w[1] == 0x09
537 && C.w[0] >= 0xfffffffffffffffbull)) {
538 // set invalid flag
539 *pfpsf |= INVALID_EXCEPTION;
540 // return Integer Indefinite
541 res = 0x8000000000000000ull;
542 BID_RETURN (res);
544 // else cases that can be rounded to a 64-bit int fall through
545 // to '1 <= q + exp <= 20'
546 } else if (q <= 19) {
547 // C * 10^(21-q) >= 0x9fffffffffffffffb
548 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
549 if (C.w[1] > 0x09 || (C.w[1] == 0x09
550 && C.w[0] >= 0xfffffffffffffffbull)) {
551 // set invalid flag
552 *pfpsf |= INVALID_EXCEPTION;
553 // return Integer Indefinite
554 res = 0x8000000000000000ull;
555 BID_RETURN (res);
557 // else cases that can be rounded to a 64-bit int fall through
558 // to '1 <= q + exp <= 20'
559 } else if (q == 20) {
560 // C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
561 C.w[0] = C1.w[0] + C1.w[0];
562 C.w[1] = C1.w[1] + C1.w[1];
563 if (C.w[0] < C1.w[0])
564 C.w[1]++;
565 if (C.w[1] > 0x01 || (C.w[1] == 0x01
566 && C.w[0] >= 0xffffffffffffffffull)) {
567 // set invalid flag
568 *pfpsf |= INVALID_EXCEPTION;
569 // return Integer Indefinite
570 res = 0x8000000000000000ull;
571 BID_RETURN (res);
573 // else cases that can be rounded to a 64-bit int fall through
574 // to '1 <= q + exp <= 20'
575 } else if (q == 21) {
576 // C >= 0x9fffffffffffffffb
577 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
578 && C1.w[0] >= 0xfffffffffffffffbull)) {
579 // set invalid flag
580 *pfpsf |= INVALID_EXCEPTION;
581 // return Integer Indefinite
582 res = 0x8000000000000000ull;
583 BID_RETURN (res);
585 // else cases that can be rounded to a 64-bit int fall through
586 // to '1 <= q + exp <= 20'
587 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
588 // C >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
589 C.w[1] = 0x09;
590 C.w[0] = 0xfffffffffffffffbull;
591 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
592 if (C1.w[1] > C.w[1]
593 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
594 // set invalid flag
595 *pfpsf |= INVALID_EXCEPTION;
596 // return Integer Indefinite
597 res = 0x8000000000000000ull;
598 BID_RETURN (res);
600 // else cases that can be rounded to a 64-bit int fall through
601 // to '1 <= q + exp <= 20'
605 // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
606 // Note: some of the cases tested for above fall through to this point
607 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
608 // set inexact flag
609 *pfpsf |= INEXACT_EXCEPTION;
610 // return 0
611 res = 0x0000000000000000ull;
612 BID_RETURN (res);
613 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
614 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
615 // res = 0
616 // else if x > 0
617 // res = +1
618 // else // if x < 0
619 // invalid exc
620 ind = q - 1;
621 if (ind <= 18) { // 0 <= ind <= 18
622 if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) {
623 res = 0x0000000000000000ull; // return 0
624 } else if (!x_sign) { // n > 0
625 res = 0x00000001; // return +1
626 } else {
627 res = 0x8000000000000000ull;
628 *pfpsf |= INVALID_EXCEPTION;
629 BID_RETURN (res);
631 } else { // 19 <= ind <= 33
632 if ((C1.w[1] < midpoint128[ind - 19].w[1])
633 || ((C1.w[1] == midpoint128[ind - 19].w[1])
634 && (C1.w[0] <= midpoint128[ind - 19].w[0]))) {
635 res = 0x0000000000000000ull; // return 0
636 } else if (!x_sign) { // n > 0
637 res = 0x00000001; // return +1
638 } else {
639 res = 0x8000000000000000ull;
640 *pfpsf |= INVALID_EXCEPTION;
641 BID_RETURN (res);
644 // set inexact flag
645 *pfpsf |= INEXACT_EXCEPTION;
646 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
647 // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
648 // to nearest to a 64-bit unsigned signed integer
649 if (x_sign) { // x <= -1
650 // set invalid flag
651 *pfpsf |= INVALID_EXCEPTION;
652 // return Integer Indefinite
653 res = 0x8000000000000000ull;
654 BID_RETURN (res);
656 // 1 <= x < 2^64-1/2 so x can be rounded
657 // to nearest to a 64-bit unsigned integer
658 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
659 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
660 // chop off ind digits from the lower part of C1
661 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
662 tmp64 = C1.w[0];
663 if (ind <= 19) {
664 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
665 } else {
666 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
667 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
669 if (C1.w[0] < tmp64)
670 C1.w[1]++;
671 // calculate C* and f*
672 // C* is actually floor(C*) in this case
673 // C* and f* need shifting and masking, as shown by
674 // shiftright128[] and maskhigh128[]
675 // 1 <= x <= 33
676 // kx = 10^(-x) = ten2mk128[ind - 1]
677 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
678 // the approximation of 10^(-x) was rounded up to 118 bits
679 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
680 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
681 Cstar.w[1] = P256.w[3];
682 Cstar.w[0] = P256.w[2];
683 fstar.w[3] = 0;
684 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
685 fstar.w[1] = P256.w[1];
686 fstar.w[0] = P256.w[0];
687 } else { // 22 <= ind - 1 <= 33
688 Cstar.w[1] = 0;
689 Cstar.w[0] = P256.w[3];
690 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
691 fstar.w[2] = P256.w[2];
692 fstar.w[1] = P256.w[1];
693 fstar.w[0] = P256.w[0];
695 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
696 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
697 // if (0 < f* < 10^(-x)) then the result is a midpoint
698 // if floor(C*) is even then C* = floor(C*) - logical right
699 // shift; C* has p decimal digits, correct by Prop. 1)
700 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
701 // shift; C* has p decimal digits, correct by Pr. 1)
702 // else
703 // C* = floor(C*) (logical right shift; C has p decimal digits,
704 // correct by Property 1)
705 // n = C* * 10^(e+x)
707 // shift right C* by Ex-128 = shiftright128[ind]
708 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
709 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
710 Cstar.w[0] =
711 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
712 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
713 } else { // 22 <= ind - 1 <= 33
714 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
716 // determine inexactness of the rounding of C*
717 // if (0 < f* - 1/2 < 10^(-x)) then
718 // the result is exact
719 // else // if (f* - 1/2 > T*) then
720 // the result is inexact
721 if (ind - 1 <= 2) {
722 if (fstar.w[1] > 0x8000000000000000ull ||
723 (fstar.w[1] == 0x8000000000000000ull
724 && fstar.w[0] > 0x0ull)) {
725 // f* > 1/2 and the result may be exact
726 tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2
727 if (tmp64 > ten2mk128trunc[ind - 1].w[1]
728 || (tmp64 == ten2mk128trunc[ind - 1].w[1]
729 && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) {
730 // set the inexact flag
731 *pfpsf |= INEXACT_EXCEPTION;
732 } // else the result is exact
733 } else { // the result is inexact; f2* <= 1/2
734 // set the inexact flag
735 *pfpsf |= INEXACT_EXCEPTION;
737 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
738 if (fstar.w[3] > 0x0 ||
739 (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) ||
740 (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] &&
741 (fstar.w[1] || fstar.w[0]))) {
742 // f2* > 1/2 and the result may be exact
743 // Calculate f2* - 1/2
744 tmp64 = fstar.w[2] - onehalf128[ind - 1];
745 tmp64A = fstar.w[3];
746 if (tmp64 > fstar.w[2])
747 tmp64A--;
748 if (tmp64A || tmp64
749 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
750 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
751 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
752 // set the inexact flag
753 *pfpsf |= INEXACT_EXCEPTION;
754 } // else the result is exact
755 } else { // the result is inexact; f2* <= 1/2
756 // set the inexact flag
757 *pfpsf |= INEXACT_EXCEPTION;
759 } else { // if 22 <= ind <= 33
760 if (fstar.w[3] > onehalf128[ind - 1] ||
761 (fstar.w[3] == onehalf128[ind - 1] &&
762 (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
763 // f2* > 1/2 and the result may be exact
764 // Calculate f2* - 1/2
765 tmp64 = fstar.w[3] - onehalf128[ind - 1];
766 if (tmp64 || fstar.w[2]
767 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
768 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
769 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
770 // set the inexact flag
771 *pfpsf |= INEXACT_EXCEPTION;
772 } // else the result is exact
773 } else { // the result is inexact; f2* <= 1/2
774 // set the inexact flag
775 *pfpsf |= INEXACT_EXCEPTION;
779 // if the result was a midpoint it was rounded away from zero, so
780 // it will need a correction
781 // check for midpoints
782 if ((fstar.w[3] == 0) && (fstar.w[2] == 0)
783 && (fstar.w[1] || fstar.w[0])
784 && (fstar.w[1] < ten2mk128trunc[ind - 1].w[1]
785 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
786 && fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) {
787 // the result is a midpoint; round to nearest
788 if (Cstar.w[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
789 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
790 Cstar.w[0]--; // Cstar.w[0] is now even
791 } // else MP in [ODD, EVEN]
793 res = Cstar.w[0]; // the result is positive
794 } else if (exp == 0) {
795 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
796 // res = C (exact)
797 res = C1.w[0];
798 } else {
799 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
800 // res = C * 10^exp (exact) - must fit in 64 bits
801 res = C1.w[0] * ten2k64[exp];
806 BID_RETURN (res);
809 /*****************************************************************************
810 * BID128_to_uint64_floor
811 ****************************************************************************/
813 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
814 bid128_to_uint64_floor, x)
816 UINT64 res;
817 UINT64 x_sign;
818 UINT64 x_exp;
819 int exp; // unbiased exponent
820 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
821 BID_UI64DOUBLE tmp1;
822 unsigned int x_nr_bits;
823 int q, ind, shift;
824 UINT128 C1, C;
825 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
826 UINT256 P256;
828 // unpack x
829 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
830 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
831 C1.w[1] = x.w[1] & MASK_COEFF;
832 C1.w[0] = x.w[0];
834 // check for NaN or Infinity
835 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
836 // x is special
837 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
838 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
839 // set invalid flag
840 *pfpsf |= INVALID_EXCEPTION;
841 // return Integer Indefinite
842 res = 0x8000000000000000ull;
843 } else { // x is QNaN
844 // set invalid flag
845 *pfpsf |= INVALID_EXCEPTION;
846 // return Integer Indefinite
847 res = 0x8000000000000000ull;
849 BID_RETURN (res);
850 } else { // x is not a NaN, so it must be infinity
851 if (!x_sign) { // x is +inf
852 // set invalid flag
853 *pfpsf |= INVALID_EXCEPTION;
854 // return Integer Indefinite
855 res = 0x8000000000000000ull;
856 } else { // x is -inf
857 // set invalid flag
858 *pfpsf |= INVALID_EXCEPTION;
859 // return Integer Indefinite
860 res = 0x8000000000000000ull;
862 BID_RETURN (res);
865 // check for non-canonical values (after the check for special values)
866 if ((C1.w[1] > 0x0001ed09bead87c0ull)
867 || (C1.w[1] == 0x0001ed09bead87c0ull
868 && (C1.w[0] > 0x378d8e63ffffffffull))
869 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
870 res = 0x0000000000000000ull;
871 BID_RETURN (res);
872 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
873 // x is 0
874 res = 0x0000000000000000ull;
875 BID_RETURN (res);
876 } else { // x is not special and is not zero
878 // if n < 0 then n cannot be converted to uint64 with RM
879 if (x_sign) { // if n < 0 and q + exp = 20
880 // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 0
881 // set invalid flag
882 *pfpsf |= INVALID_EXCEPTION;
883 // return Integer Indefinite
884 res = 0x8000000000000000ull;
885 BID_RETURN (res);
887 // q = nr. of decimal digits in x
888 // determine first the nr. of bits in x
889 if (C1.w[1] == 0) {
890 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
891 // split the 64-bit value in two 32-bit halves to avoid rounding errors
892 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
893 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
894 x_nr_bits =
895 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
896 } else { // x < 2^32
897 tmp1.d = (double) (C1.w[0]); // exact conversion
898 x_nr_bits =
899 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
901 } else { // if x < 2^53
902 tmp1.d = (double) C1.w[0]; // exact conversion
903 x_nr_bits =
904 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
906 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
907 tmp1.d = (double) C1.w[1]; // exact conversion
908 x_nr_bits =
909 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
911 q = nr_digits[x_nr_bits - 1].digits;
912 if (q == 0) {
913 q = nr_digits[x_nr_bits - 1].digits1;
914 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
915 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
916 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
917 q++;
919 exp = (x_exp >> 49) - 6176;
920 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
921 // set invalid flag
922 *pfpsf |= INVALID_EXCEPTION;
923 // return Integer Indefinite
924 res = 0x8000000000000000ull;
925 BID_RETURN (res);
926 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
927 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
928 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
929 // the cases that do not fit are identified here; the ones that fit
930 // fall through and will be handled with other cases further,
931 // under '1 <= q + exp <= 20'
932 // if n > 0 and q + exp = 20
933 // if n >= 2^64 then n is too large
934 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
935 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
936 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
937 // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
938 if (q == 1) {
939 // C * 10^20 >= 0xa0000000000000000
940 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
941 if (C.w[1] >= 0x0a) {
942 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
943 // set invalid flag
944 *pfpsf |= INVALID_EXCEPTION;
945 // return Integer Indefinite
946 res = 0x8000000000000000ull;
947 BID_RETURN (res);
949 // else cases that can be rounded to a 64-bit int fall through
950 // to '1 <= q + exp <= 20'
951 } else if (q <= 19) {
952 // C * 10^(21-q) >= 0xa0000000000000000
953 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
954 if (C.w[1] >= 0x0a) {
955 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
956 // set invalid flag
957 *pfpsf |= INVALID_EXCEPTION;
958 // return Integer Indefinite
959 res = 0x8000000000000000ull;
960 BID_RETURN (res);
962 // else cases that can be rounded to a 64-bit int fall through
963 // to '1 <= q + exp <= 20'
964 } else if (q == 20) {
965 // C >= 0x10000000000000000
966 if (C1.w[1] >= 0x01) {
967 // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
968 // set invalid flag
969 *pfpsf |= INVALID_EXCEPTION;
970 // return Integer Indefinite
971 res = 0x8000000000000000ull;
972 BID_RETURN (res);
974 // else cases that can be rounded to a 64-bit int fall through
975 // to '1 <= q + exp <= 20'
976 } else if (q == 21) {
977 // C >= 0xa0000000000000000
978 if (C1.w[1] >= 0x0a) {
979 // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
980 // set invalid flag
981 *pfpsf |= INVALID_EXCEPTION;
982 // return Integer Indefinite
983 res = 0x8000000000000000ull;
984 BID_RETURN (res);
986 // else cases that can be rounded to a 64-bit int fall through
987 // to '1 <= q + exp <= 20'
988 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
989 // C >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
990 C.w[1] = 0x0a;
991 C.w[0] = 0x0000000000000000ull;
992 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
993 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
994 // set invalid flag
995 *pfpsf |= INVALID_EXCEPTION;
996 // return Integer Indefinite
997 res = 0x8000000000000000ull;
998 BID_RETURN (res);
1000 // else cases that can be rounded to a 64-bit int fall through
1001 // to '1 <= q + exp <= 20'
1004 // n is not too large to be converted to int64 if 0 <= n < 2^64
1005 // Note: some of the cases tested for above fall through to this point
1006 if ((q + exp) <= 0) { // n = +0.[0...0]c(0)c(1)...c(q-1)
1007 // return 0
1008 res = 0x0000000000000000ull;
1009 BID_RETURN (res);
1010 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
1011 // 1 <= x < 2^64 so x can be rounded
1012 // down to a 64-bit unsigned signed integer
1013 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
1014 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
1015 // chop off ind digits from the lower part of C1
1016 // C1 fits in 127 bits
1017 // calculate C* and f*
1018 // C* is actually floor(C*) in this case
1019 // C* and f* need shifting and masking, as shown by
1020 // shiftright128[] and maskhigh128[]
1021 // 1 <= x <= 33
1022 // kx = 10^(-x) = ten2mk128[ind - 1]
1023 // C* = C1 * 10^(-x)
1024 // the approximation of 10^(-x) was rounded up to 118 bits
1025 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
1026 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1027 Cstar.w[1] = P256.w[3];
1028 Cstar.w[0] = P256.w[2];
1029 } else { // 22 <= ind - 1 <= 33
1030 Cstar.w[1] = 0;
1031 Cstar.w[0] = P256.w[3];
1033 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1034 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1035 // C* = floor(C*) (logical right shift; C has p decimal digits,
1036 // correct by Property 1)
1037 // n = C* * 10^(e+x)
1039 // shift right C* by Ex-128 = shiftright128[ind]
1040 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
1041 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1042 Cstar.w[0] =
1043 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
1044 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1045 } else { // 22 <= ind - 1 <= 33
1046 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
1048 res = Cstar.w[0]; // the result is positive
1049 } else if (exp == 0) {
1050 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
1051 // res = C (exact)
1052 res = C1.w[0];
1053 } else {
1054 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
1055 // res = C * 10^exp (exact) - must fit in 64 bits
1056 res = C1.w[0] * ten2k64[exp];
1061 BID_RETURN (res);
1064 /*****************************************************************************
1065 * BID128_to_uint64_xfloor
1066 ****************************************************************************/
1068 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
1069 bid128_to_uint64_xfloor, x)
1071 UINT64 res;
1072 UINT64 x_sign;
1073 UINT64 x_exp;
1074 int exp; // unbiased exponent
1075 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1076 BID_UI64DOUBLE tmp1;
1077 unsigned int x_nr_bits;
1078 int q, ind, shift;
1079 UINT128 C1, C;
1080 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1081 UINT256 fstar;
1082 UINT256 P256;
1084 // unpack x
1085 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1086 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
1087 C1.w[1] = x.w[1] & MASK_COEFF;
1088 C1.w[0] = x.w[0];
1090 // check for NaN or Infinity
1091 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1092 // x is special
1093 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
1094 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
1095 // set invalid flag
1096 *pfpsf |= INVALID_EXCEPTION;
1097 // return Integer Indefinite
1098 res = 0x8000000000000000ull;
1099 } else { // x is QNaN
1100 // set invalid flag
1101 *pfpsf |= INVALID_EXCEPTION;
1102 // return Integer Indefinite
1103 res = 0x8000000000000000ull;
1105 BID_RETURN (res);
1106 } else { // x is not a NaN, so it must be infinity
1107 if (!x_sign) { // x is +inf
1108 // set invalid flag
1109 *pfpsf |= INVALID_EXCEPTION;
1110 // return Integer Indefinite
1111 res = 0x8000000000000000ull;
1112 } else { // x is -inf
1113 // set invalid flag
1114 *pfpsf |= INVALID_EXCEPTION;
1115 // return Integer Indefinite
1116 res = 0x8000000000000000ull;
1118 BID_RETURN (res);
1121 // check for non-canonical values (after the check for special values)
1122 if ((C1.w[1] > 0x0001ed09bead87c0ull)
1123 || (C1.w[1] == 0x0001ed09bead87c0ull
1124 && (C1.w[0] > 0x378d8e63ffffffffull))
1125 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
1126 res = 0x0000000000000000ull;
1127 BID_RETURN (res);
1128 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1129 // x is 0
1130 res = 0x0000000000000000ull;
1131 BID_RETURN (res);
1132 } else { // x is not special and is not zero
1134 // if n < 0 then n cannot be converted to uint64 with RM
1135 if (x_sign) { // if n < 0 and q + exp = 20
1136 // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 0
1137 // set invalid flag
1138 *pfpsf |= INVALID_EXCEPTION;
1139 // return Integer Indefinite
1140 res = 0x8000000000000000ull;
1141 BID_RETURN (res);
1143 // q = nr. of decimal digits in x
1144 // determine first the nr. of bits in x
1145 if (C1.w[1] == 0) {
1146 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
1147 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1148 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
1149 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
1150 x_nr_bits =
1151 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1152 } else { // x < 2^32
1153 tmp1.d = (double) (C1.w[0]); // exact conversion
1154 x_nr_bits =
1155 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1157 } else { // if x < 2^53
1158 tmp1.d = (double) C1.w[0]; // exact conversion
1159 x_nr_bits =
1160 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1162 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1163 tmp1.d = (double) C1.w[1]; // exact conversion
1164 x_nr_bits =
1165 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1167 q = nr_digits[x_nr_bits - 1].digits;
1168 if (q == 0) {
1169 q = nr_digits[x_nr_bits - 1].digits1;
1170 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
1171 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
1172 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
1173 q++;
1175 exp = (x_exp >> 49) - 6176;
1176 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1177 // set invalid flag
1178 *pfpsf |= INVALID_EXCEPTION;
1179 // return Integer Indefinite
1180 res = 0x8000000000000000ull;
1181 BID_RETURN (res);
1182 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
1183 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1184 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
1185 // the cases that do not fit are identified here; the ones that fit
1186 // fall through and will be handled with other cases further,
1187 // under '1 <= q + exp <= 20'
1188 // if n > 0 and q + exp = 20
1189 // if n >= 2^64 then n is too large
1190 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
1191 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
1192 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
1193 // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
1194 if (q == 1) {
1195 // C * 10^20 >= 0xa0000000000000000
1196 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
1197 if (C.w[1] >= 0x0a) {
1198 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
1199 // set invalid flag
1200 *pfpsf |= INVALID_EXCEPTION;
1201 // return Integer Indefinite
1202 res = 0x8000000000000000ull;
1203 BID_RETURN (res);
1205 // else cases that can be rounded to a 64-bit int fall through
1206 // to '1 <= q + exp <= 20'
1207 } else if (q <= 19) {
1208 // C * 10^(21-q) >= 0xa0000000000000000
1209 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
1210 if (C.w[1] >= 0x0a) {
1211 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
1212 // set invalid flag
1213 *pfpsf |= INVALID_EXCEPTION;
1214 // return Integer Indefinite
1215 res = 0x8000000000000000ull;
1216 BID_RETURN (res);
1218 // else cases that can be rounded to a 64-bit int fall through
1219 // to '1 <= q + exp <= 20'
1220 } else if (q == 20) {
1221 // C >= 0x10000000000000000
1222 if (C1.w[1] >= 0x01) {
1223 // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
1224 // set invalid flag
1225 *pfpsf |= INVALID_EXCEPTION;
1226 // return Integer Indefinite
1227 res = 0x8000000000000000ull;
1228 BID_RETURN (res);
1230 // else cases that can be rounded to a 64-bit int fall through
1231 // to '1 <= q + exp <= 20'
1232 } else if (q == 21) {
1233 // C >= 0xa0000000000000000
1234 if (C1.w[1] >= 0x0a) {
1235 // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
1236 // set invalid flag
1237 *pfpsf |= INVALID_EXCEPTION;
1238 // return Integer Indefinite
1239 res = 0x8000000000000000ull;
1240 BID_RETURN (res);
1242 // else cases that can be rounded to a 64-bit int fall through
1243 // to '1 <= q + exp <= 20'
1244 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
1245 // C >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
1246 C.w[1] = 0x0a;
1247 C.w[0] = 0x0000000000000000ull;
1248 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
1249 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
1250 // set invalid flag
1251 *pfpsf |= INVALID_EXCEPTION;
1252 // return Integer Indefinite
1253 res = 0x8000000000000000ull;
1254 BID_RETURN (res);
1256 // else cases that can be rounded to a 64-bit int fall through
1257 // to '1 <= q + exp <= 20'
1260 // n is not too large to be converted to int64 if 0 <= n < 2^64
1261 // Note: some of the cases tested for above fall through to this point
1262 if ((q + exp) <= 0) { // n = +0.[0...0]c(0)c(1)...c(q-1)
1263 // set inexact flag
1264 *pfpsf |= INEXACT_EXCEPTION;
1265 // return 0
1266 res = 0x0000000000000000ull;
1267 BID_RETURN (res);
1268 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
1269 // 1 <= x < 2^64 so x can be rounded
1270 // down to a 64-bit unsigned signed integer
1271 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
1272 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
1273 // chop off ind digits from the lower part of C1
1274 // C1 fits in 127 bits
1275 // calculate C* and f*
1276 // C* is actually floor(C*) in this case
1277 // C* and f* need shifting and masking, as shown by
1278 // shiftright128[] and maskhigh128[]
1279 // 1 <= x <= 33
1280 // kx = 10^(-x) = ten2mk128[ind - 1]
1281 // C* = C1 * 10^(-x)
1282 // the approximation of 10^(-x) was rounded up to 118 bits
1283 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
1284 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1285 Cstar.w[1] = P256.w[3];
1286 Cstar.w[0] = P256.w[2];
1287 fstar.w[3] = 0;
1288 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
1289 fstar.w[1] = P256.w[1];
1290 fstar.w[0] = P256.w[0];
1291 } else { // 22 <= ind - 1 <= 33
1292 Cstar.w[1] = 0;
1293 Cstar.w[0] = P256.w[3];
1294 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
1295 fstar.w[2] = P256.w[2];
1296 fstar.w[1] = P256.w[1];
1297 fstar.w[0] = P256.w[0];
1299 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1300 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1301 // C* = floor(C*) (logical right shift; C has p decimal digits,
1302 // correct by Property 1)
1303 // n = C* * 10^(e+x)
1305 // shift right C* by Ex-128 = shiftright128[ind]
1306 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
1307 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1308 Cstar.w[0] =
1309 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
1310 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1311 } else { // 22 <= ind - 1 <= 33
1312 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
1314 // determine inexactness of the rounding of C*
1315 // if (0 < f* < 10^(-x)) then
1316 // the result is exact
1317 // else // if (f* > T*) then
1318 // the result is inexact
1319 if (ind - 1 <= 2) {
1320 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] ||
1321 (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] &&
1322 fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1323 // set the inexact flag
1324 *pfpsf |= INEXACT_EXCEPTION;
1325 } // else the result is exact
1326 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
1327 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1328 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1329 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1330 // set the inexact flag
1331 *pfpsf |= INEXACT_EXCEPTION;
1332 } // else the result is exact
1333 } else { // if 22 <= ind <= 33
1334 if (fstar.w[3] || fstar.w[2]
1335 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1336 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1337 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1338 // set the inexact flag
1339 *pfpsf |= INEXACT_EXCEPTION;
1340 } // else the result is exact
1343 res = Cstar.w[0]; // the result is positive
1344 } else if (exp == 0) {
1345 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
1346 // res = C (exact)
1347 res = C1.w[0];
1348 } else {
1349 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
1350 // res = C * 10^exp (exact) - must fit in 64 bits
1351 res = C1.w[0] * ten2k64[exp];
1356 BID_RETURN (res);
1359 /*****************************************************************************
1360 * BID128_to_uint64_ceil
1361 ****************************************************************************/
1363 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_ceil,
1366 UINT64 res;
1367 UINT64 x_sign;
1368 UINT64 x_exp;
1369 int exp; // unbiased exponent
1370 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1371 BID_UI64DOUBLE tmp1;
1372 unsigned int x_nr_bits;
1373 int q, ind, shift;
1374 UINT128 C1, C;
1375 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1376 UINT256 fstar;
1377 UINT256 P256;
1379 // unpack x
1380 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1381 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
1382 C1.w[1] = x.w[1] & MASK_COEFF;
1383 C1.w[0] = x.w[0];
1385 // check for NaN or Infinity
1386 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1387 // x is special
1388 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
1389 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
1390 // set invalid flag
1391 *pfpsf |= INVALID_EXCEPTION;
1392 // return Integer Indefinite
1393 res = 0x8000000000000000ull;
1394 } else { // x is QNaN
1395 // set invalid flag
1396 *pfpsf |= INVALID_EXCEPTION;
1397 // return Integer Indefinite
1398 res = 0x8000000000000000ull;
1400 BID_RETURN (res);
1401 } else { // x is not a NaN, so it must be infinity
1402 if (!x_sign) { // x is +inf
1403 // set invalid flag
1404 *pfpsf |= INVALID_EXCEPTION;
1405 // return Integer Indefinite
1406 res = 0x8000000000000000ull;
1407 } else { // x is -inf
1408 // set invalid flag
1409 *pfpsf |= INVALID_EXCEPTION;
1410 // return Integer Indefinite
1411 res = 0x8000000000000000ull;
1413 BID_RETURN (res);
1416 // check for non-canonical values (after the check for special values)
1417 if ((C1.w[1] > 0x0001ed09bead87c0ull)
1418 || (C1.w[1] == 0x0001ed09bead87c0ull
1419 && (C1.w[0] > 0x378d8e63ffffffffull))
1420 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
1421 res = 0x0000000000000000ull;
1422 BID_RETURN (res);
1423 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1424 // x is 0
1425 res = 0x0000000000000000ull;
1426 BID_RETURN (res);
1427 } else { // x is not special and is not zero
1429 // q = nr. of decimal digits in x
1430 // determine first the nr. of bits in x
1431 if (C1.w[1] == 0) {
1432 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
1433 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1434 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
1435 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
1436 x_nr_bits =
1437 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1438 } else { // x < 2^32
1439 tmp1.d = (double) (C1.w[0]); // exact conversion
1440 x_nr_bits =
1441 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1443 } else { // if x < 2^53
1444 tmp1.d = (double) C1.w[0]; // exact conversion
1445 x_nr_bits =
1446 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1448 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1449 tmp1.d = (double) C1.w[1]; // exact conversion
1450 x_nr_bits =
1451 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1453 q = nr_digits[x_nr_bits - 1].digits;
1454 if (q == 0) {
1455 q = nr_digits[x_nr_bits - 1].digits1;
1456 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
1457 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
1458 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
1459 q++;
1461 exp = (x_exp >> 49) - 6176;
1462 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1463 // set invalid flag
1464 *pfpsf |= INVALID_EXCEPTION;
1465 // return Integer Indefinite
1466 res = 0x8000000000000000ull;
1467 BID_RETURN (res);
1468 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
1469 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1470 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
1471 // the cases that do not fit are identified here; the ones that fit
1472 // fall through and will be handled with other cases further,
1473 // under '1 <= q + exp <= 20'
1474 if (x_sign) { // if n < 0 and q + exp = 20
1475 // if n <= -1 then n cannot be converted to uint64 with RZ
1476 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
1477 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
1478 // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
1479 if (q == 21) {
1480 // C >= a
1481 if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
1482 // set invalid flag
1483 *pfpsf |= INVALID_EXCEPTION;
1484 // return Integer Indefinite
1485 res = 0x8000000000000000ull;
1486 BID_RETURN (res);
1488 // else cases that can be rounded to 64-bit unsigned int fall through
1489 // to '1 <= q + exp <= 20'
1490 } else {
1491 // if 1 <= q <= 20
1492 // C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
1493 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
1494 // C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
1495 // set invalid flag
1496 *pfpsf |= INVALID_EXCEPTION;
1497 // return Integer Indefinite
1498 res = 0x8000000000000000ull;
1499 BID_RETURN (res);
1501 } else { // if n > 0 and q + exp = 20
1502 // if n > 2^64 - 1 then n is too large
1503 // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
1504 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
1505 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 > 10 * (2^64 - 1)
1506 // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=34
1507 if (q == 1) {
1508 // C * 10^20 > 0x9fffffffffffffff6
1509 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
1510 if (C.w[1] > 0x09 || (C.w[1] == 0x09
1511 && C.w[0] > 0xfffffffffffffff6ull)) {
1512 // set invalid flag
1513 *pfpsf |= INVALID_EXCEPTION;
1514 // return Integer Indefinite
1515 res = 0x8000000000000000ull;
1516 BID_RETURN (res);
1518 // else cases that can be rounded to a 64-bit int fall through
1519 // to '1 <= q + exp <= 20'
1520 } else if (q <= 19) {
1521 // C * 10^(21-q) > 0x9fffffffffffffff6
1522 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
1523 if (C.w[1] > 0x09 || (C.w[1] == 0x09
1524 && C.w[0] > 0xfffffffffffffff6ull)) {
1525 // set invalid flag
1526 *pfpsf |= INVALID_EXCEPTION;
1527 // return Integer Indefinite
1528 res = 0x8000000000000000ull;
1529 BID_RETURN (res);
1531 // else cases that can be rounded to a 64-bit int fall through
1532 // to '1 <= q + exp <= 20'
1533 } else if (q == 20) {
1534 // C > 0xffffffffffffffff
1535 if (C1.w[1]) {
1536 // set invalid flag
1537 *pfpsf |= INVALID_EXCEPTION;
1538 // return Integer Indefinite
1539 res = 0x8000000000000000ull;
1540 BID_RETURN (res);
1542 // else cases that can be rounded to a 64-bit int fall through
1543 // to '1 <= q + exp <= 20'
1544 } else if (q == 21) {
1545 // C > 0x9fffffffffffffff6
1546 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
1547 && C1.w[0] > 0xfffffffffffffff6ull)) {
1548 // set invalid flag
1549 *pfpsf |= INVALID_EXCEPTION;
1550 // return Integer Indefinite
1551 res = 0x8000000000000000ull;
1552 BID_RETURN (res);
1554 // else cases that can be rounded to a 64-bit int fall through
1555 // to '1 <= q + exp <= 20'
1556 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
1557 // C > 10^(q-21) * 0x9fffffffffffffff6 max 44 bits x 68 bits
1558 C.w[1] = 0x09;
1559 C.w[0] = 0xfffffffffffffff6ull;
1560 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
1561 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) {
1562 // set invalid flag
1563 *pfpsf |= INVALID_EXCEPTION;
1564 // return Integer Indefinite
1565 res = 0x8000000000000000ull;
1566 BID_RETURN (res);
1568 // else cases that can be rounded to a 64-bit int fall through
1569 // to '1 <= q + exp <= 20'
1573 // n is not too large to be converted to int64 if -1 < n <= 2^64 - 1
1574 // Note: some of the cases tested for above fall through to this point
1575 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1576 // return 0 or 1
1577 if (x_sign)
1578 res = 0x0000000000000000ull;
1579 else
1580 res = 0x0000000000000001ull;
1581 BID_RETURN (res);
1582 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
1583 // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
1584 // to zero to a 64-bit unsigned signed integer
1585 if (x_sign) { // x <= -1
1586 // set invalid flag
1587 *pfpsf |= INVALID_EXCEPTION;
1588 // return Integer Indefinite
1589 res = 0x8000000000000000ull;
1590 BID_RETURN (res);
1592 // 1 <= x <= 2^64 - 1 so x can be rounded
1593 // to zero to a 64-bit unsigned integer
1594 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
1595 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
1596 // chop off ind digits from the lower part of C1
1597 // C1 fits in 127 bits
1598 // calculate C* and f*
1599 // C* is actually floor(C*) in this case
1600 // C* and f* need shifting and masking, as shown by
1601 // shiftright128[] and maskhigh128[]
1602 // 1 <= x <= 33
1603 // kx = 10^(-x) = ten2mk128[ind - 1]
1604 // C* = C1 * 10^(-x)
1605 // the approximation of 10^(-x) was rounded up to 118 bits
1606 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
1607 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1608 Cstar.w[1] = P256.w[3];
1609 Cstar.w[0] = P256.w[2];
1610 fstar.w[3] = 0;
1611 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
1612 fstar.w[1] = P256.w[1];
1613 fstar.w[0] = P256.w[0];
1614 } else { // 22 <= ind - 1 <= 33
1615 Cstar.w[1] = 0;
1616 Cstar.w[0] = P256.w[3];
1617 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
1618 fstar.w[2] = P256.w[2];
1619 fstar.w[1] = P256.w[1];
1620 fstar.w[0] = P256.w[0];
1622 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1623 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1624 // C* = floor(C*) (logical right shift; C has p decimal digits,
1625 // correct by Property 1)
1626 // n = C* * 10^(e+x)
1628 // shift right C* by Ex-128 = shiftright128[ind]
1629 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
1630 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1631 Cstar.w[0] =
1632 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
1633 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1634 } else { // 22 <= ind - 1 <= 33
1635 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
1637 // if the result is positive and inexact, need to add 1 to it
1639 // determine inexactness of the rounding of C*
1640 // if (0 < f* < 10^(-x)) then
1641 // the result is exact
1642 // else // if (f* > T*) then
1643 // the result is inexact
1644 if (ind - 1 <= 2) {
1645 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1646 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1647 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1648 if (!x_sign) { // positive and inexact
1649 Cstar.w[0]++;
1650 if (Cstar.w[0] == 0x0)
1651 Cstar.w[1]++;
1653 } // else the result is exact
1654 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
1655 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1656 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1657 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1658 if (!x_sign) { // positive and inexact
1659 Cstar.w[0]++;
1660 if (Cstar.w[0] == 0x0)
1661 Cstar.w[1]++;
1663 } // else the result is exact
1664 } else { // if 22 <= ind <= 33
1665 if (fstar.w[3] || fstar.w[2]
1666 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1667 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1668 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1669 if (!x_sign) { // positive and inexact
1670 Cstar.w[0]++;
1671 if (Cstar.w[0] == 0x0)
1672 Cstar.w[1]++;
1674 } // else the result is exact
1677 res = Cstar.w[0]; // the result is positive
1678 } else if (exp == 0) {
1679 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
1680 // res = C (exact)
1681 res = C1.w[0];
1682 } else {
1683 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
1684 // res = C * 10^exp (exact) - must fit in 64 bits
1685 res = C1.w[0] * ten2k64[exp];
1690 BID_RETURN (res);
1693 /*****************************************************************************
1694 * BID128_to_uint64_xceil
1695 ****************************************************************************/
1697 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
1698 bid128_to_uint64_xceil, x)
1700 UINT64 res;
1701 UINT64 x_sign;
1702 UINT64 x_exp;
1703 int exp; // unbiased exponent
1704 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1705 BID_UI64DOUBLE tmp1;
1706 unsigned int x_nr_bits;
1707 int q, ind, shift;
1708 UINT128 C1, C;
1709 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1710 UINT256 fstar;
1711 UINT256 P256;
1713 // unpack x
1714 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1715 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
1716 C1.w[1] = x.w[1] & MASK_COEFF;
1717 C1.w[0] = x.w[0];
1719 // check for NaN or Infinity
1720 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1721 // x is special
1722 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
1723 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
1724 // set invalid flag
1725 *pfpsf |= INVALID_EXCEPTION;
1726 // return Integer Indefinite
1727 res = 0x8000000000000000ull;
1728 } else { // x is QNaN
1729 // set invalid flag
1730 *pfpsf |= INVALID_EXCEPTION;
1731 // return Integer Indefinite
1732 res = 0x8000000000000000ull;
1734 BID_RETURN (res);
1735 } else { // x is not a NaN, so it must be infinity
1736 if (!x_sign) { // x is +inf
1737 // set invalid flag
1738 *pfpsf |= INVALID_EXCEPTION;
1739 // return Integer Indefinite
1740 res = 0x8000000000000000ull;
1741 } else { // x is -inf
1742 // set invalid flag
1743 *pfpsf |= INVALID_EXCEPTION;
1744 // return Integer Indefinite
1745 res = 0x8000000000000000ull;
1747 BID_RETURN (res);
1750 // check for non-canonical values (after the check for special values)
1751 if ((C1.w[1] > 0x0001ed09bead87c0ull)
1752 || (C1.w[1] == 0x0001ed09bead87c0ull
1753 && (C1.w[0] > 0x378d8e63ffffffffull))
1754 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
1755 res = 0x0000000000000000ull;
1756 BID_RETURN (res);
1757 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1758 // x is 0
1759 res = 0x0000000000000000ull;
1760 BID_RETURN (res);
1761 } else { // x is not special and is not zero
1763 // q = nr. of decimal digits in x
1764 // determine first the nr. of bits in x
1765 if (C1.w[1] == 0) {
1766 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
1767 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1768 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
1769 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
1770 x_nr_bits =
1771 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1772 } else { // x < 2^32
1773 tmp1.d = (double) (C1.w[0]); // exact conversion
1774 x_nr_bits =
1775 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1777 } else { // if x < 2^53
1778 tmp1.d = (double) C1.w[0]; // exact conversion
1779 x_nr_bits =
1780 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1782 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1783 tmp1.d = (double) C1.w[1]; // exact conversion
1784 x_nr_bits =
1785 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1787 q = nr_digits[x_nr_bits - 1].digits;
1788 if (q == 0) {
1789 q = nr_digits[x_nr_bits - 1].digits1;
1790 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
1791 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
1792 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
1793 q++;
1795 exp = (x_exp >> 49) - 6176;
1796 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1797 // set invalid flag
1798 *pfpsf |= INVALID_EXCEPTION;
1799 // return Integer Indefinite
1800 res = 0x8000000000000000ull;
1801 BID_RETURN (res);
1802 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
1803 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1804 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
1805 // the cases that do not fit are identified here; the ones that fit
1806 // fall through and will be handled with other cases further,
1807 // under '1 <= q + exp <= 20'
1808 if (x_sign) { // if n < 0 and q + exp = 20
1809 // if n <= -1 then n cannot be converted to uint64 with RZ
1810 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
1811 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
1812 // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
1813 if (q == 21) {
1814 // C >= a
1815 if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
1816 // set invalid flag
1817 *pfpsf |= INVALID_EXCEPTION;
1818 // return Integer Indefinite
1819 res = 0x8000000000000000ull;
1820 BID_RETURN (res);
1822 // else cases that can be rounded to 64-bit unsigned int fall through
1823 // to '1 <= q + exp <= 20'
1824 } else {
1825 // if 1 <= q <= 20
1826 // C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
1827 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
1828 // C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
1829 // set invalid flag
1830 *pfpsf |= INVALID_EXCEPTION;
1831 // return Integer Indefinite
1832 res = 0x8000000000000000ull;
1833 BID_RETURN (res);
1835 } else { // if n > 0 and q + exp = 20
1836 // if n > 2^64 - 1 then n is too large
1837 // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
1838 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
1839 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 > 10 * (2^64 - 1)
1840 // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=34
1841 if (q == 1) {
1842 // C * 10^20 > 0x9fffffffffffffff6
1843 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
1844 if (C.w[1] > 0x09 || (C.w[1] == 0x09
1845 && C.w[0] > 0xfffffffffffffff6ull)) {
1846 // set invalid flag
1847 *pfpsf |= INVALID_EXCEPTION;
1848 // return Integer Indefinite
1849 res = 0x8000000000000000ull;
1850 BID_RETURN (res);
1852 // else cases that can be rounded to a 64-bit int fall through
1853 // to '1 <= q + exp <= 20'
1854 } else if (q <= 19) {
1855 // C * 10^(21-q) > 0x9fffffffffffffff6
1856 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
1857 if (C.w[1] > 0x09 || (C.w[1] == 0x09
1858 && C.w[0] > 0xfffffffffffffff6ull)) {
1859 // set invalid flag
1860 *pfpsf |= INVALID_EXCEPTION;
1861 // return Integer Indefinite
1862 res = 0x8000000000000000ull;
1863 BID_RETURN (res);
1865 // else cases that can be rounded to a 64-bit int fall through
1866 // to '1 <= q + exp <= 20'
1867 } else if (q == 20) {
1868 // C > 0xffffffffffffffff
1869 if (C1.w[1]) {
1870 // set invalid flag
1871 *pfpsf |= INVALID_EXCEPTION;
1872 // return Integer Indefinite
1873 res = 0x8000000000000000ull;
1874 BID_RETURN (res);
1876 // else cases that can be rounded to a 64-bit int fall through
1877 // to '1 <= q + exp <= 20'
1878 } else if (q == 21) {
1879 // C > 0x9fffffffffffffff6
1880 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
1881 && C1.w[0] > 0xfffffffffffffff6ull)) {
1882 // set invalid flag
1883 *pfpsf |= INVALID_EXCEPTION;
1884 // return Integer Indefinite
1885 res = 0x8000000000000000ull;
1886 BID_RETURN (res);
1888 // else cases that can be rounded to a 64-bit int fall through
1889 // to '1 <= q + exp <= 20'
1890 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
1891 // C > 10^(q-21) * 0x9fffffffffffffff6 max 44 bits x 68 bits
1892 C.w[1] = 0x09;
1893 C.w[0] = 0xfffffffffffffff6ull;
1894 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
1895 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) {
1896 // set invalid flag
1897 *pfpsf |= INVALID_EXCEPTION;
1898 // return Integer Indefinite
1899 res = 0x8000000000000000ull;
1900 BID_RETURN (res);
1902 // else cases that can be rounded to a 64-bit int fall through
1903 // to '1 <= q + exp <= 20'
1907 // n is not too large to be converted to int64 if -1 < n <= 2^64 - 1
1908 // Note: some of the cases tested for above fall through to this point
1909 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1910 // set inexact flag
1911 *pfpsf |= INEXACT_EXCEPTION;
1912 // return 0 or 1
1913 if (x_sign)
1914 res = 0x0000000000000000ull;
1915 else
1916 res = 0x0000000000000001ull;
1917 BID_RETURN (res);
1918 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
1919 // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
1920 // to zero to a 64-bit unsigned signed integer
1921 if (x_sign) { // x <= -1
1922 // set invalid flag
1923 *pfpsf |= INVALID_EXCEPTION;
1924 // return Integer Indefinite
1925 res = 0x8000000000000000ull;
1926 BID_RETURN (res);
1928 // 1 <= x <= 2^64 - 1 so x can be rounded
1929 // to zero to a 64-bit unsigned integer
1930 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
1931 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
1932 // chop off ind digits from the lower part of C1
1933 // C1 fits in 127 bits
1934 // calculate C* and f*
1935 // C* is actually floor(C*) in this case
1936 // C* and f* need shifting and masking, as shown by
1937 // shiftright128[] and maskhigh128[]
1938 // 1 <= x <= 33
1939 // kx = 10^(-x) = ten2mk128[ind - 1]
1940 // C* = C1 * 10^(-x)
1941 // the approximation of 10^(-x) was rounded up to 118 bits
1942 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
1943 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1944 Cstar.w[1] = P256.w[3];
1945 Cstar.w[0] = P256.w[2];
1946 fstar.w[3] = 0;
1947 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
1948 fstar.w[1] = P256.w[1];
1949 fstar.w[0] = P256.w[0];
1950 } else { // 22 <= ind - 1 <= 33
1951 Cstar.w[1] = 0;
1952 Cstar.w[0] = P256.w[3];
1953 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
1954 fstar.w[2] = P256.w[2];
1955 fstar.w[1] = P256.w[1];
1956 fstar.w[0] = P256.w[0];
1958 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1959 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1960 // C* = floor(C*) (logical right shift; C has p decimal digits,
1961 // correct by Property 1)
1962 // n = C* * 10^(e+x)
1964 // shift right C* by Ex-128 = shiftright128[ind]
1965 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
1966 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
1967 Cstar.w[0] =
1968 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
1969 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1970 } else { // 22 <= ind - 1 <= 33
1971 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
1973 // if the result is positive and inexact, need to add 1 to it
1975 // determine inexactness of the rounding of C*
1976 // if (0 < f* < 10^(-x)) then
1977 // the result is exact
1978 // else // if (f* > T*) then
1979 // the result is inexact
1980 if (ind - 1 <= 2) {
1981 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1982 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1983 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1984 if (!x_sign) { // positive and inexact
1985 Cstar.w[0]++;
1986 if (Cstar.w[0] == 0x0)
1987 Cstar.w[1]++;
1989 // set the inexact flag
1990 *pfpsf |= INEXACT_EXCEPTION;
1991 } // else the result is exact
1992 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
1993 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
1994 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
1995 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
1996 if (!x_sign) { // positive and inexact
1997 Cstar.w[0]++;
1998 if (Cstar.w[0] == 0x0)
1999 Cstar.w[1]++;
2001 // set the inexact flag
2002 *pfpsf |= INEXACT_EXCEPTION;
2003 } // else the result is exact
2004 } else { // if 22 <= ind <= 33
2005 if (fstar.w[3] || fstar.w[2]
2006 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
2007 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
2008 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
2009 if (!x_sign) { // positive and inexact
2010 Cstar.w[0]++;
2011 if (Cstar.w[0] == 0x0)
2012 Cstar.w[1]++;
2014 // set the inexact flag
2015 *pfpsf |= INEXACT_EXCEPTION;
2016 } // else the result is exact
2019 res = Cstar.w[0]; // the result is positive
2020 } else if (exp == 0) {
2021 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
2022 // res = C (exact)
2023 res = C1.w[0];
2024 } else {
2025 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
2026 // res = C * 10^exp (exact) - must fit in 64 bits
2027 res = C1.w[0] * ten2k64[exp];
2032 BID_RETURN (res);
2035 /*****************************************************************************
2036 * BID128_to_uint64_int
2037 ****************************************************************************/
2039 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_int,
2042 UINT64 res;
2043 UINT64 x_sign;
2044 UINT64 x_exp;
2045 int exp; // unbiased exponent
2046 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2047 BID_UI64DOUBLE tmp1;
2048 unsigned int x_nr_bits;
2049 int q, ind, shift;
2050 UINT128 C1, C;
2051 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2052 UINT256 P256;
2054 // unpack x
2055 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
2056 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
2057 C1.w[1] = x.w[1] & MASK_COEFF;
2058 C1.w[0] = x.w[0];
2060 // check for NaN or Infinity
2061 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2062 // x is special
2063 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
2064 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
2065 // set invalid flag
2066 *pfpsf |= INVALID_EXCEPTION;
2067 // return Integer Indefinite
2068 res = 0x8000000000000000ull;
2069 } else { // x is QNaN
2070 // set invalid flag
2071 *pfpsf |= INVALID_EXCEPTION;
2072 // return Integer Indefinite
2073 res = 0x8000000000000000ull;
2075 BID_RETURN (res);
2076 } else { // x is not a NaN, so it must be infinity
2077 if (!x_sign) { // x is +inf
2078 // set invalid flag
2079 *pfpsf |= INVALID_EXCEPTION;
2080 // return Integer Indefinite
2081 res = 0x8000000000000000ull;
2082 } else { // x is -inf
2083 // set invalid flag
2084 *pfpsf |= INVALID_EXCEPTION;
2085 // return Integer Indefinite
2086 res = 0x8000000000000000ull;
2088 BID_RETURN (res);
2091 // check for non-canonical values (after the check for special values)
2092 if ((C1.w[1] > 0x0001ed09bead87c0ull)
2093 || (C1.w[1] == 0x0001ed09bead87c0ull
2094 && (C1.w[0] > 0x378d8e63ffffffffull))
2095 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
2096 res = 0x0000000000000000ull;
2097 BID_RETURN (res);
2098 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2099 // x is 0
2100 res = 0x0000000000000000ull;
2101 BID_RETURN (res);
2102 } else { // x is not special and is not zero
2104 // q = nr. of decimal digits in x
2105 // determine first the nr. of bits in x
2106 if (C1.w[1] == 0) {
2107 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
2108 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2109 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
2110 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
2111 x_nr_bits =
2112 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2113 } else { // x < 2^32
2114 tmp1.d = (double) (C1.w[0]); // exact conversion
2115 x_nr_bits =
2116 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2118 } else { // if x < 2^53
2119 tmp1.d = (double) C1.w[0]; // exact conversion
2120 x_nr_bits =
2121 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2123 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2124 tmp1.d = (double) C1.w[1]; // exact conversion
2125 x_nr_bits =
2126 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2128 q = nr_digits[x_nr_bits - 1].digits;
2129 if (q == 0) {
2130 q = nr_digits[x_nr_bits - 1].digits1;
2131 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
2132 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
2133 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
2134 q++;
2136 exp = (x_exp >> 49) - 6176;
2138 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2139 // set invalid flag
2140 *pfpsf |= INVALID_EXCEPTION;
2141 // return Integer Indefinite
2142 res = 0x8000000000000000ull;
2143 BID_RETURN (res);
2144 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
2145 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2146 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
2147 // the cases that do not fit are identified here; the ones that fit
2148 // fall through and will be handled with other cases further,
2149 // under '1 <= q + exp <= 20'
2150 if (x_sign) { // if n < 0 and q + exp = 20
2151 // if n <= -1 then n cannot be converted to uint64 with RZ
2152 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
2153 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
2154 // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
2155 if (q == 21) {
2156 // C >= a
2157 if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
2158 // set invalid flag
2159 *pfpsf |= INVALID_EXCEPTION;
2160 // return Integer Indefinite
2161 res = 0x8000000000000000ull;
2162 BID_RETURN (res);
2164 // else cases that can be rounded to 64-bit unsigned int fall through
2165 // to '1 <= q + exp <= 20'
2166 } else {
2167 // if 1 <= q <= 20
2168 // C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
2169 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2170 // C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
2171 // set invalid flag
2172 *pfpsf |= INVALID_EXCEPTION;
2173 // return Integer Indefinite
2174 res = 0x8000000000000000ull;
2175 BID_RETURN (res);
2177 } else { // if n > 0 and q + exp = 20
2178 // if n >= 2^64 then n is too large
2179 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
2180 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
2181 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
2182 // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
2183 if (q == 1) {
2184 // C * 10^20 >= 0xa0000000000000000
2185 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
2186 if (C.w[1] >= 0x0a) {
2187 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
2188 // set invalid flag
2189 *pfpsf |= INVALID_EXCEPTION;
2190 // return Integer Indefinite
2191 res = 0x8000000000000000ull;
2192 BID_RETURN (res);
2194 // else cases that can be rounded to a 64-bit int fall through
2195 // to '1 <= q + exp <= 20'
2196 } else if (q <= 19) {
2197 // C * 10^(21-q) >= 0xa0000000000000000
2198 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
2199 if (C.w[1] >= 0x0a) {
2200 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
2201 // set invalid flag
2202 *pfpsf |= INVALID_EXCEPTION;
2203 // return Integer Indefinite
2204 res = 0x8000000000000000ull;
2205 BID_RETURN (res);
2207 // else cases that can be rounded to a 64-bit int fall through
2208 // to '1 <= q + exp <= 20'
2209 } else if (q == 20) {
2210 // C >= 0x10000000000000000
2211 if (C1.w[1] >= 0x01) {
2212 // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
2213 // set invalid flag
2214 *pfpsf |= INVALID_EXCEPTION;
2215 // return Integer Indefinite
2216 res = 0x8000000000000000ull;
2217 BID_RETURN (res);
2219 // else cases that can be rounded to a 64-bit int fall through
2220 // to '1 <= q + exp <= 20'
2221 } else if (q == 21) {
2222 // C >= 0xa0000000000000000
2223 if (C1.w[1] >= 0x0a) {
2224 // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
2225 // set invalid flag
2226 *pfpsf |= INVALID_EXCEPTION;
2227 // return Integer Indefinite
2228 res = 0x8000000000000000ull;
2229 BID_RETURN (res);
2231 // else cases that can be rounded to a 64-bit int fall through
2232 // to '1 <= q + exp <= 20'
2233 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2234 // C >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
2235 C.w[1] = 0x0a;
2236 C.w[0] = 0x0000000000000000ull;
2237 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
2238 if (C1.w[1] > C.w[1]
2239 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
2240 // set invalid flag
2241 *pfpsf |= INVALID_EXCEPTION;
2242 // return Integer Indefinite
2243 res = 0x8000000000000000ull;
2244 BID_RETURN (res);
2246 // else cases that can be rounded to a 64-bit int fall through
2247 // to '1 <= q + exp <= 20'
2251 // n is not too large to be converted to int64 if -1 < n < 2^64
2252 // Note: some of the cases tested for above fall through to this point
2253 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2254 // return 0
2255 res = 0x0000000000000000ull;
2256 BID_RETURN (res);
2257 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
2258 // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
2259 // to zero to a 64-bit unsigned signed integer
2260 if (x_sign) { // x <= -1
2261 // set invalid flag
2262 *pfpsf |= INVALID_EXCEPTION;
2263 // return Integer Indefinite
2264 res = 0x8000000000000000ull;
2265 BID_RETURN (res);
2267 // 1 <= x < 2^64 so x can be rounded
2268 // to zero to a 64-bit unsigned integer
2269 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
2270 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
2271 // chop off ind digits from the lower part of C1
2272 // C1 fits in 127 bits
2273 // calculate C* and f*
2274 // C* is actually floor(C*) in this case
2275 // C* and f* need shifting and masking, as shown by
2276 // shiftright128[] and maskhigh128[]
2277 // 1 <= x <= 33
2278 // kx = 10^(-x) = ten2mk128[ind - 1]
2279 // C* = C1 * 10^(-x)
2280 // the approximation of 10^(-x) was rounded up to 118 bits
2281 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
2282 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2283 Cstar.w[1] = P256.w[3];
2284 Cstar.w[0] = P256.w[2];
2285 } else { // 22 <= ind - 1 <= 33
2286 Cstar.w[1] = 0;
2287 Cstar.w[0] = P256.w[3];
2289 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2290 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2291 // C* = floor(C*) (logical right shift; C has p decimal digits,
2292 // correct by Property 1)
2293 // n = C* * 10^(e+x)
2295 // shift right C* by Ex-128 = shiftright128[ind]
2296 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
2297 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2298 Cstar.w[0] =
2299 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
2300 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2301 } else { // 22 <= ind - 1 <= 33
2302 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
2304 res = Cstar.w[0]; // the result is positive
2305 } else if (exp == 0) {
2306 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
2307 // res = C (exact)
2308 res = C1.w[0];
2309 } else {
2310 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
2311 // res = C * 10^exp (exact) - must fit in 64 bits
2312 res = C1.w[0] * ten2k64[exp];
2317 BID_RETURN (res);
2320 /*****************************************************************************
2321 * BID128_to_uint64_xint
2322 ****************************************************************************/
2324 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_xint,
2327 UINT64 res;
2328 UINT64 x_sign;
2329 UINT64 x_exp;
2330 int exp; // unbiased exponent
2331 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2332 BID_UI64DOUBLE tmp1;
2333 unsigned int x_nr_bits;
2334 int q, ind, shift;
2335 UINT128 C1, C;
2336 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2337 UINT256 fstar;
2338 UINT256 P256;
2340 // unpack x
2341 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
2342 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
2343 C1.w[1] = x.w[1] & MASK_COEFF;
2344 C1.w[0] = x.w[0];
2346 // check for NaN or Infinity
2347 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2348 // x is special
2349 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
2350 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
2351 // set invalid flag
2352 *pfpsf |= INVALID_EXCEPTION;
2353 // return Integer Indefinite
2354 res = 0x8000000000000000ull;
2355 } else { // x is QNaN
2356 // set invalid flag
2357 *pfpsf |= INVALID_EXCEPTION;
2358 // return Integer Indefinite
2359 res = 0x8000000000000000ull;
2361 BID_RETURN (res);
2362 } else { // x is not a NaN, so it must be infinity
2363 if (!x_sign) { // x is +inf
2364 // set invalid flag
2365 *pfpsf |= INVALID_EXCEPTION;
2366 // return Integer Indefinite
2367 res = 0x8000000000000000ull;
2368 } else { // x is -inf
2369 // set invalid flag
2370 *pfpsf |= INVALID_EXCEPTION;
2371 // return Integer Indefinite
2372 res = 0x8000000000000000ull;
2374 BID_RETURN (res);
2377 // check for non-canonical values (after the check for special values)
2378 if ((C1.w[1] > 0x0001ed09bead87c0ull)
2379 || (C1.w[1] == 0x0001ed09bead87c0ull
2380 && (C1.w[0] > 0x378d8e63ffffffffull))
2381 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
2382 res = 0x0000000000000000ull;
2383 BID_RETURN (res);
2384 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2385 // x is 0
2386 res = 0x0000000000000000ull;
2387 BID_RETURN (res);
2388 } else { // x is not special and is not zero
2390 // q = nr. of decimal digits in x
2391 // determine first the nr. of bits in x
2392 if (C1.w[1] == 0) {
2393 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
2394 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2395 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
2396 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
2397 x_nr_bits =
2398 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2399 } else { // x < 2^32
2400 tmp1.d = (double) (C1.w[0]); // exact conversion
2401 x_nr_bits =
2402 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2404 } else { // if x < 2^53
2405 tmp1.d = (double) C1.w[0]; // exact conversion
2406 x_nr_bits =
2407 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2409 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2410 tmp1.d = (double) C1.w[1]; // exact conversion
2411 x_nr_bits =
2412 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2414 q = nr_digits[x_nr_bits - 1].digits;
2415 if (q == 0) {
2416 q = nr_digits[x_nr_bits - 1].digits1;
2417 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
2418 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
2419 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
2420 q++;
2422 exp = (x_exp >> 49) - 6176;
2423 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2424 // set invalid flag
2425 *pfpsf |= INVALID_EXCEPTION;
2426 // return Integer Indefinite
2427 res = 0x8000000000000000ull;
2428 BID_RETURN (res);
2429 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
2430 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2431 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
2432 // the cases that do not fit are identified here; the ones that fit
2433 // fall through and will be handled with other cases further,
2434 // under '1 <= q + exp <= 20'
2435 if (x_sign) { // if n < 0 and q + exp = 20
2436 // if n <= -1 then n cannot be converted to uint64 with RZ
2437 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
2438 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
2439 // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
2440 if (q == 21) {
2441 // C >= a
2442 if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
2443 // set invalid flag
2444 *pfpsf |= INVALID_EXCEPTION;
2445 // return Integer Indefinite
2446 res = 0x8000000000000000ull;
2447 BID_RETURN (res);
2449 // else cases that can be rounded to 64-bit unsigned int fall through
2450 // to '1 <= q + exp <= 20'
2451 } else {
2452 // if 1 <= q <= 20
2453 // C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
2454 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2455 // C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
2456 // set invalid flag
2457 *pfpsf |= INVALID_EXCEPTION;
2458 // return Integer Indefinite
2459 res = 0x8000000000000000ull;
2460 BID_RETURN (res);
2462 } else { // if n > 0 and q + exp = 20
2463 // if n >= 2^64 then n is too large
2464 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
2465 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
2466 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
2467 // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
2468 if (q == 1) {
2469 // C * 10^20 >= 0xa0000000000000000
2470 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
2471 if (C.w[1] >= 0x0a) {
2472 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
2473 // set invalid flag
2474 *pfpsf |= INVALID_EXCEPTION;
2475 // return Integer Indefinite
2476 res = 0x8000000000000000ull;
2477 BID_RETURN (res);
2479 // else cases that can be rounded to a 64-bit int fall through
2480 // to '1 <= q + exp <= 20'
2481 } else if (q <= 19) {
2482 // C * 10^(21-q) >= 0xa0000000000000000
2483 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
2484 if (C.w[1] >= 0x0a) {
2485 // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
2486 // set invalid flag
2487 *pfpsf |= INVALID_EXCEPTION;
2488 // return Integer Indefinite
2489 res = 0x8000000000000000ull;
2490 BID_RETURN (res);
2492 // else cases that can be rounded to a 64-bit int fall through
2493 // to '1 <= q + exp <= 20'
2494 } else if (q == 20) {
2495 // C >= 0x10000000000000000
2496 if (C1.w[1] >= 0x01) {
2497 // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
2498 // set invalid flag
2499 *pfpsf |= INVALID_EXCEPTION;
2500 // return Integer Indefinite
2501 res = 0x8000000000000000ull;
2502 BID_RETURN (res);
2504 // else cases that can be rounded to a 64-bit int fall through
2505 // to '1 <= q + exp <= 20'
2506 } else if (q == 21) {
2507 // C >= 0xa0000000000000000
2508 if (C1.w[1] >= 0x0a) {
2509 // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
2510 // set invalid flag
2511 *pfpsf |= INVALID_EXCEPTION;
2512 // return Integer Indefinite
2513 res = 0x8000000000000000ull;
2514 BID_RETURN (res);
2516 // else cases that can be rounded to a 64-bit int fall through
2517 // to '1 <= q + exp <= 20'
2518 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2519 // C >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
2520 C.w[1] = 0x0a;
2521 C.w[0] = 0x0000000000000000ull;
2522 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
2523 if (C1.w[1] > C.w[1]
2524 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
2525 // set invalid flag
2526 *pfpsf |= INVALID_EXCEPTION;
2527 // return Integer Indefinite
2528 res = 0x8000000000000000ull;
2529 BID_RETURN (res);
2531 // else cases that can be rounded to a 64-bit int fall through
2532 // to '1 <= q + exp <= 20'
2536 // n is not too large to be converted to int64 if -1 < n < 2^64
2537 // Note: some of the cases tested for above fall through to this point
2538 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2539 // set inexact flag
2540 *pfpsf |= INEXACT_EXCEPTION;
2541 // return 0
2542 res = 0x0000000000000000ull;
2543 BID_RETURN (res);
2544 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
2545 // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
2546 // to zero to a 64-bit unsigned signed integer
2547 if (x_sign) { // x <= -1
2548 // set invalid flag
2549 *pfpsf |= INVALID_EXCEPTION;
2550 // return Integer Indefinite
2551 res = 0x8000000000000000ull;
2552 BID_RETURN (res);
2554 // 1 <= x < 2^64 so x can be rounded
2555 // to zero to a 64-bit unsigned integer
2556 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
2557 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
2558 // chop off ind digits from the lower part of C1
2559 // C1 fits in 127 bits
2560 // calculate C* and f*
2561 // C* is actually floor(C*) in this case
2562 // C* and f* need shifting and masking, as shown by
2563 // shiftright128[] and maskhigh128[]
2564 // 1 <= x <= 33
2565 // kx = 10^(-x) = ten2mk128[ind - 1]
2566 // C* = C1 * 10^(-x)
2567 // the approximation of 10^(-x) was rounded up to 118 bits
2568 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
2569 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2570 Cstar.w[1] = P256.w[3];
2571 Cstar.w[0] = P256.w[2];
2572 fstar.w[3] = 0;
2573 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
2574 fstar.w[1] = P256.w[1];
2575 fstar.w[0] = P256.w[0];
2576 } else { // 22 <= ind - 1 <= 33
2577 Cstar.w[1] = 0;
2578 Cstar.w[0] = P256.w[3];
2579 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
2580 fstar.w[2] = P256.w[2];
2581 fstar.w[1] = P256.w[1];
2582 fstar.w[0] = P256.w[0];
2584 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2585 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2586 // C* = floor(C*) (logical right shift; C has p decimal digits,
2587 // correct by Property 1)
2588 // n = C* * 10^(e+x)
2590 // shift right C* by Ex-128 = shiftright128[ind]
2591 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
2592 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2593 Cstar.w[0] =
2594 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
2595 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2596 } else { // 22 <= ind - 1 <= 33
2597 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
2599 // determine inexactness of the rounding of C*
2600 // if (0 < f* < 10^(-x)) then
2601 // the result is exact
2602 // else // if (f* > T*) then
2603 // the result is inexact
2604 if (ind - 1 <= 2) {
2605 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
2606 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
2607 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
2608 // set the inexact flag
2609 *pfpsf |= INEXACT_EXCEPTION;
2610 } // else the result is exact
2611 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
2612 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
2613 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
2614 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
2615 // set the inexact flag
2616 *pfpsf |= INEXACT_EXCEPTION;
2617 } // else the result is exact
2618 } else { // if 22 <= ind <= 33
2619 if (fstar.w[3] || fstar.w[2]
2620 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
2621 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
2622 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
2623 // set the inexact flag
2624 *pfpsf |= INEXACT_EXCEPTION;
2625 } // else the result is exact
2628 res = Cstar.w[0]; // the result is positive
2629 } else if (exp == 0) {
2630 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
2631 // res = C (exact)
2632 res = C1.w[0];
2633 } else {
2634 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
2635 // res = C * 10^exp (exact) - must fit in 64 bits
2636 res = C1.w[0] * ten2k64[exp];
2641 BID_RETURN (res);
2644 /*****************************************************************************
2645 * BID128_to_uint64_rninta
2646 ****************************************************************************/
2648 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
2649 bid128_to_uint64_rninta, x)
2651 UINT64 res;
2652 UINT64 x_sign;
2653 UINT64 x_exp;
2654 int exp; // unbiased exponent
2655 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2656 UINT64 tmp64;
2657 BID_UI64DOUBLE tmp1;
2658 unsigned int x_nr_bits;
2659 int q, ind, shift;
2660 UINT128 C1, C;
2661 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2662 UINT256 P256;
2664 // unpack x
2665 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
2666 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
2667 C1.w[1] = x.w[1] & MASK_COEFF;
2668 C1.w[0] = x.w[0];
2670 // check for NaN or Infinity
2671 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2672 // x is special
2673 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
2674 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
2675 // set invalid flag
2676 *pfpsf |= INVALID_EXCEPTION;
2677 // return Integer Indefinite
2678 res = 0x8000000000000000ull;
2679 } else { // x is QNaN
2680 // set invalid flag
2681 *pfpsf |= INVALID_EXCEPTION;
2682 // return Integer Indefinite
2683 res = 0x8000000000000000ull;
2685 BID_RETURN (res);
2686 } else { // x is not a NaN, so it must be infinity
2687 if (!x_sign) { // x is +inf
2688 // set invalid flag
2689 *pfpsf |= INVALID_EXCEPTION;
2690 // return Integer Indefinite
2691 res = 0x8000000000000000ull;
2692 } else { // x is -inf
2693 // set invalid flag
2694 *pfpsf |= INVALID_EXCEPTION;
2695 // return Integer Indefinite
2696 res = 0x8000000000000000ull;
2698 BID_RETURN (res);
2701 // check for non-canonical values (after the check for special values)
2702 if ((C1.w[1] > 0x0001ed09bead87c0ull)
2703 || (C1.w[1] == 0x0001ed09bead87c0ull
2704 && (C1.w[0] > 0x378d8e63ffffffffull))
2705 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
2706 res = 0x0000000000000000ull;
2707 BID_RETURN (res);
2708 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2709 // x is 0
2710 res = 0x0000000000000000ull;
2711 BID_RETURN (res);
2712 } else { // x is not special and is not zero
2714 // q = nr. of decimal digits in x
2715 // determine first the nr. of bits in x
2716 if (C1.w[1] == 0) {
2717 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
2718 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2719 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
2720 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
2721 x_nr_bits =
2722 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2723 } else { // x < 2^32
2724 tmp1.d = (double) (C1.w[0]); // exact conversion
2725 x_nr_bits =
2726 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2728 } else { // if x < 2^53
2729 tmp1.d = (double) C1.w[0]; // exact conversion
2730 x_nr_bits =
2731 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2733 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2734 tmp1.d = (double) C1.w[1]; // exact conversion
2735 x_nr_bits =
2736 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2738 q = nr_digits[x_nr_bits - 1].digits;
2739 if (q == 0) {
2740 q = nr_digits[x_nr_bits - 1].digits1;
2741 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
2742 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
2743 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
2744 q++;
2746 exp = (x_exp >> 49) - 6176;
2747 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2748 // set invalid flag
2749 *pfpsf |= INVALID_EXCEPTION;
2750 // return Integer Indefinite
2751 res = 0x8000000000000000ull;
2752 BID_RETURN (res);
2753 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
2754 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2755 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
2756 // the cases that do not fit are identified here; the ones that fit
2757 // fall through and will be handled with other cases further,
2758 // under '1 <= q + exp <= 20'
2759 if (x_sign) { // if n < 0 and q + exp = 20
2760 // if n <= -1/2 then n cannot be converted to uint64 with RN
2761 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1/2
2762 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x05, 1<=q<=34
2763 // <=> C * 10^(21-q) >= 0x05, 1<=q<=34
2764 if (q == 21) {
2765 // C >= 5
2766 if (C1.w[1] != 0 || C1.w[0] >= 0x05ull) {
2767 // set invalid flag
2768 *pfpsf |= INVALID_EXCEPTION;
2769 // return Integer Indefinite
2770 res = 0x8000000000000000ull;
2771 BID_RETURN (res);
2773 // else cases that can be rounded to 64-bit unsigned int fall through
2774 // to '1 <= q + exp <= 20'
2775 } else {
2776 // if 1 <= q <= 20
2777 // C * 10^(21-q) >= 5 is true because C >= 1 and 10^(21-q) >= 10
2778 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2779 // C >= 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
2780 // set invalid flag
2781 *pfpsf |= INVALID_EXCEPTION;
2782 // return Integer Indefinite
2783 res = 0x8000000000000000ull;
2784 BID_RETURN (res);
2786 } else { // if n > 0 and q + exp = 20
2787 // if n >= 2^64 - 1/2 then n is too large
2788 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
2789 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
2790 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
2791 // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
2792 if (q == 1) {
2793 // C * 10^20 >= 0x9fffffffffffffffb
2794 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
2795 if (C.w[1] > 0x09 || (C.w[1] == 0x09
2796 && C.w[0] >= 0xfffffffffffffffbull)) {
2797 // set invalid flag
2798 *pfpsf |= INVALID_EXCEPTION;
2799 // return Integer Indefinite
2800 res = 0x8000000000000000ull;
2801 BID_RETURN (res);
2803 // else cases that can be rounded to a 64-bit int fall through
2804 // to '1 <= q + exp <= 20'
2805 } else if (q <= 19) {
2806 // C * 10^(21-q) >= 0x9fffffffffffffffb
2807 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
2808 if (C.w[1] > 0x09 || (C.w[1] == 0x09
2809 && C.w[0] >= 0xfffffffffffffffbull)) {
2810 // set invalid flag
2811 *pfpsf |= INVALID_EXCEPTION;
2812 // return Integer Indefinite
2813 res = 0x8000000000000000ull;
2814 BID_RETURN (res);
2816 // else cases that can be rounded to a 64-bit int fall through
2817 // to '1 <= q + exp <= 20'
2818 } else if (q == 20) {
2819 // C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
2820 C.w[0] = C1.w[0] + C1.w[0];
2821 C.w[1] = C1.w[1] + C1.w[1];
2822 if (C.w[0] < C1.w[0])
2823 C.w[1]++;
2824 if (C.w[1] > 0x01 || (C.w[1] == 0x01
2825 && C.w[0] >= 0xffffffffffffffffull)) {
2826 // set invalid flag
2827 *pfpsf |= INVALID_EXCEPTION;
2828 // return Integer Indefinite
2829 res = 0x8000000000000000ull;
2830 BID_RETURN (res);
2832 // else cases that can be rounded to a 64-bit int fall through
2833 // to '1 <= q + exp <= 20'
2834 } else if (q == 21) {
2835 // C >= 0x9fffffffffffffffb
2836 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
2837 && C1.w[0] >= 0xfffffffffffffffbull)) {
2838 // set invalid flag
2839 *pfpsf |= INVALID_EXCEPTION;
2840 // return Integer Indefinite
2841 res = 0x8000000000000000ull;
2842 BID_RETURN (res);
2844 // else cases that can be rounded to a 64-bit int fall through
2845 // to '1 <= q + exp <= 20'
2846 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
2847 // C >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
2848 C.w[1] = 0x09;
2849 C.w[0] = 0xfffffffffffffffbull;
2850 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
2851 if (C1.w[1] > C.w[1]
2852 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
2853 // set invalid flag
2854 *pfpsf |= INVALID_EXCEPTION;
2855 // return Integer Indefinite
2856 res = 0x8000000000000000ull;
2857 BID_RETURN (res);
2859 // else cases that can be rounded to a 64-bit int fall through
2860 // to '1 <= q + exp <= 20'
2864 // n is not too large to be converted to int64 if -1/2 < n < 2^64 - 1/2
2865 // Note: some of the cases tested for above fall through to this point
2866 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2867 // return 0
2868 res = 0x0000000000000000ull;
2869 BID_RETURN (res);
2870 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2871 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
2872 // res = 0
2873 // else if x > 0
2874 // res = +1
2875 // else // if x < 0
2876 // invalid exc
2877 ind = q - 1;
2878 if (ind <= 18) { // 0 <= ind <= 18
2879 if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) {
2880 res = 0x0000000000000000ull; // return 0
2881 } else if (!x_sign) { // n > 0
2882 res = 0x00000001; // return +1
2883 } else {
2884 // set invalid flag
2885 *pfpsf |= INVALID_EXCEPTION;
2886 // return Integer Indefinite
2887 res = 0x8000000000000000ull;
2888 BID_RETURN (res);
2890 } else { // 19 <= ind <= 33
2891 if ((C1.w[1] < midpoint128[ind - 19].w[1])
2892 || ((C1.w[1] == midpoint128[ind - 19].w[1])
2893 && (C1.w[0] < midpoint128[ind - 19].w[0]))) {
2894 res = 0x0000000000000000ull; // return 0
2895 } else if (!x_sign) { // n > 0
2896 res = 0x00000001; // return +1
2897 } else {
2898 // set invalid flag
2899 *pfpsf |= INVALID_EXCEPTION;
2900 // return Integer Indefinite
2901 res = 0x8000000000000000ull;
2902 BID_RETURN (res);
2905 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
2906 // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
2907 // to nearest to a 64-bit unsigned signed integer
2908 if (x_sign) { // x <= -1
2909 // set invalid flag
2910 *pfpsf |= INVALID_EXCEPTION;
2911 // return Integer Indefinite
2912 res = 0x8000000000000000ull;
2913 BID_RETURN (res);
2915 // 1 <= x < 2^64-1/2 so x can be rounded
2916 // to nearest to a 64-bit unsigned integer
2917 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
2918 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
2919 // chop off ind digits from the lower part of C1
2920 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
2921 tmp64 = C1.w[0];
2922 if (ind <= 19) {
2923 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
2924 } else {
2925 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
2926 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
2928 if (C1.w[0] < tmp64)
2929 C1.w[1]++;
2930 // calculate C* and f*
2931 // C* is actually floor(C*) in this case
2932 // C* and f* need shifting and masking, as shown by
2933 // shiftright128[] and maskhigh128[]
2934 // 1 <= x <= 33
2935 // kx = 10^(-x) = ten2mk128[ind - 1]
2936 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2937 // the approximation of 10^(-x) was rounded up to 118 bits
2938 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
2939 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2940 Cstar.w[1] = P256.w[3];
2941 Cstar.w[0] = P256.w[2];
2942 } else { // 22 <= ind - 1 <= 33
2943 Cstar.w[1] = 0;
2944 Cstar.w[0] = P256.w[3];
2946 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2947 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2948 // if (0 < f* < 10^(-x)) then the result is a midpoint
2949 // if floor(C*) is even then C* = floor(C*) - logical right
2950 // shift; C* has p decimal digits, correct by Prop. 1)
2951 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2952 // shift; C* has p decimal digits, correct by Pr. 1)
2953 // else
2954 // C* = floor(C*) (logical right shift; C has p decimal digits,
2955 // correct by Property 1)
2956 // n = C* * 10^(e+x)
2958 // shift right C* by Ex-128 = shiftright128[ind]
2959 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
2960 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2961 Cstar.w[0] =
2962 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
2963 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2964 } else { // 22 <= ind - 1 <= 33
2965 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
2968 // if the result was a midpoint it was rounded away from zero
2969 res = Cstar.w[0]; // the result is positive
2970 } else if (exp == 0) {
2971 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
2972 // res = C (exact)
2973 res = C1.w[0];
2974 } else {
2975 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
2976 // res = C * 10^exp (exact) - must fit in 64 bits
2977 res = C1.w[0] * ten2k64[exp];
2982 BID_RETURN (res);
2985 /*****************************************************************************
2986 * BID128_to_uint64_xrninta
2987 ****************************************************************************/
2989 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
2990 bid128_to_uint64_xrninta, x)
2992 UINT64 res;
2993 UINT64 x_sign;
2994 UINT64 x_exp;
2995 int exp; // unbiased exponent
2996 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2997 UINT64 tmp64, tmp64A;
2998 BID_UI64DOUBLE tmp1;
2999 unsigned int x_nr_bits;
3000 int q, ind, shift;
3001 UINT128 C1, C;
3002 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
3003 UINT256 fstar;
3004 UINT256 P256;
3006 // unpack x
3007 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
3008 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
3009 C1.w[1] = x.w[1] & MASK_COEFF;
3010 C1.w[0] = x.w[0];
3012 // check for NaN or Infinity
3013 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
3014 // x is special
3015 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
3016 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
3017 // set invalid flag
3018 *pfpsf |= INVALID_EXCEPTION;
3019 // return Integer Indefinite
3020 res = 0x8000000000000000ull;
3021 } else { // x is QNaN
3022 // set invalid flag
3023 *pfpsf |= INVALID_EXCEPTION;
3024 // return Integer Indefinite
3025 res = 0x8000000000000000ull;
3027 BID_RETURN (res);
3028 } else { // x is not a NaN, so it must be infinity
3029 if (!x_sign) { // x is +inf
3030 // set invalid flag
3031 *pfpsf |= INVALID_EXCEPTION;
3032 // return Integer Indefinite
3033 res = 0x8000000000000000ull;
3034 } else { // x is -inf
3035 // set invalid flag
3036 *pfpsf |= INVALID_EXCEPTION;
3037 // return Integer Indefinite
3038 res = 0x8000000000000000ull;
3040 BID_RETURN (res);
3043 // check for non-canonical values (after the check for special values)
3044 if ((C1.w[1] > 0x0001ed09bead87c0ull)
3045 || (C1.w[1] == 0x0001ed09bead87c0ull
3046 && (C1.w[0] > 0x378d8e63ffffffffull))
3047 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
3048 res = 0x0000000000000000ull;
3049 BID_RETURN (res);
3050 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
3051 // x is 0
3052 res = 0x0000000000000000ull;
3053 BID_RETURN (res);
3054 } else { // x is not special and is not zero
3056 // q = nr. of decimal digits in x
3057 // determine first the nr. of bits in x
3058 if (C1.w[1] == 0) {
3059 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
3060 // split the 64-bit value in two 32-bit halves to avoid rounding errors
3061 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
3062 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
3063 x_nr_bits =
3064 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
3065 } else { // x < 2^32
3066 tmp1.d = (double) (C1.w[0]); // exact conversion
3067 x_nr_bits =
3068 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
3070 } else { // if x < 2^53
3071 tmp1.d = (double) C1.w[0]; // exact conversion
3072 x_nr_bits =
3073 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
3075 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
3076 tmp1.d = (double) C1.w[1]; // exact conversion
3077 x_nr_bits =
3078 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
3080 q = nr_digits[x_nr_bits - 1].digits;
3081 if (q == 0) {
3082 q = nr_digits[x_nr_bits - 1].digits1;
3083 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
3084 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
3085 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
3086 q++;
3088 exp = (x_exp >> 49) - 6176;
3090 if ((q + exp) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
3091 // set invalid flag
3092 *pfpsf |= INVALID_EXCEPTION;
3093 // return Integer Indefinite
3094 res = 0x8000000000000000ull;
3095 BID_RETURN (res);
3096 } else if ((q + exp) == 20) { // x = c(0)c(1)...c(19).c(20)...c(q-1)
3097 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
3098 // so x rounded to an integer may or may not fit in an unsigned 64-bit int
3099 // the cases that do not fit are identified here; the ones that fit
3100 // fall through and will be handled with other cases further,
3101 // under '1 <= q + exp <= 20'
3102 if (x_sign) { // if n < 0 and q + exp = 20
3103 // if n <= -1/2 then n cannot be converted to uint64 with RN
3104 // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1/2
3105 // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x05, 1<=q<=34
3106 // <=> C * 10^(21-q) >= 0x05, 1<=q<=34
3107 if (q == 21) {
3108 // C >= 5
3109 if (C1.w[1] != 0 || C1.w[0] >= 0x05ull) {
3110 // set invalid flag
3111 *pfpsf |= INVALID_EXCEPTION;
3112 // return Integer Indefinite
3113 res = 0x8000000000000000ull;
3114 BID_RETURN (res);
3116 // else cases that can be rounded to 64-bit unsigned int fall through
3117 // to '1 <= q + exp <= 20'
3118 } else {
3119 // if 1 <= q <= 20
3120 // C * 10^(21-q) >= 5 is true because C >= 1 and 10^(21-q) >= 10
3121 // if 22 <= q <= 34 => 1 <= q - 21 <= 13
3122 // C >= 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
3123 // set invalid flag
3124 *pfpsf |= INVALID_EXCEPTION;
3125 // return Integer Indefinite
3126 res = 0x8000000000000000ull;
3127 BID_RETURN (res);
3129 } else { // if n > 0 and q + exp = 20
3130 // if n >= 2^64 - 1/2 then n is too large
3131 // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
3132 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
3133 // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
3134 // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
3135 if (q == 1) {
3136 // C * 10^20 >= 0x9fffffffffffffffb
3137 __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]); // 10^20 * C
3138 if (C.w[1] > 0x09 || (C.w[1] == 0x09
3139 && C.w[0] >= 0xfffffffffffffffbull)) {
3140 // set invalid flag
3141 *pfpsf |= INVALID_EXCEPTION;
3142 // return Integer Indefinite
3143 res = 0x8000000000000000ull;
3144 BID_RETURN (res);
3146 // else cases that can be rounded to a 64-bit int fall through
3147 // to '1 <= q + exp <= 20'
3148 } else if (q <= 19) {
3149 // C * 10^(21-q) >= 0x9fffffffffffffffb
3150 __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
3151 if (C.w[1] > 0x09 || (C.w[1] == 0x09
3152 && C.w[0] >= 0xfffffffffffffffbull)) {
3153 // set invalid flag
3154 *pfpsf |= INVALID_EXCEPTION;
3155 // return Integer Indefinite
3156 res = 0x8000000000000000ull;
3157 BID_RETURN (res);
3159 // else cases that can be rounded to a 64-bit int fall through
3160 // to '1 <= q + exp <= 20'
3161 } else if (q == 20) {
3162 // C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
3163 C.w[0] = C1.w[0] + C1.w[0];
3164 C.w[1] = C1.w[1] + C1.w[1];
3165 if (C.w[0] < C1.w[0])
3166 C.w[1]++;
3167 if (C.w[1] > 0x01 || (C.w[1] == 0x01
3168 && C.w[0] >= 0xffffffffffffffffull)) {
3169 // set invalid flag
3170 *pfpsf |= INVALID_EXCEPTION;
3171 // return Integer Indefinite
3172 res = 0x8000000000000000ull;
3173 BID_RETURN (res);
3175 // else cases that can be rounded to a 64-bit int fall through
3176 // to '1 <= q + exp <= 20'
3177 } else if (q == 21) {
3178 // C >= 0x9fffffffffffffffb
3179 if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
3180 && C1.w[0] >= 0xfffffffffffffffbull)) {
3181 // set invalid flag
3182 *pfpsf |= INVALID_EXCEPTION;
3183 // return Integer Indefinite
3184 res = 0x8000000000000000ull;
3185 BID_RETURN (res);
3187 // else cases that can be rounded to a 64-bit int fall through
3188 // to '1 <= q + exp <= 20'
3189 } else { // if 22 <= q <= 34 => 1 <= q - 21 <= 13
3190 // C >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
3191 C.w[1] = 0x09;
3192 C.w[0] = 0xfffffffffffffffbull;
3193 __mul_128x64_to_128 (C, ten2k64[q - 21], C);
3194 if (C1.w[1] > C.w[1]
3195 || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
3196 // set invalid flag
3197 *pfpsf |= INVALID_EXCEPTION;
3198 // return Integer Indefinite
3199 res = 0x8000000000000000ull;
3200 BID_RETURN (res);
3202 // else cases that can be rounded to a 64-bit int fall through
3203 // to '1 <= q + exp <= 20'
3207 // n is not too large to be converted to int64 if -1/2 < n < 2^64 - 1/2
3208 // Note: some of the cases tested for above fall through to this point
3209 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
3210 // set inexact flag
3211 *pfpsf |= INEXACT_EXCEPTION;
3212 // return 0
3213 res = 0x0000000000000000ull;
3214 BID_RETURN (res);
3215 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
3216 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
3217 // res = 0
3218 // else if x > 0
3219 // res = +1
3220 // else // if x < 0
3221 // invalid exc
3222 ind = q - 1;
3223 if (ind <= 18) { // 0 <= ind <= 18
3224 if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) {
3225 res = 0x0000000000000000ull; // return 0
3226 } else if (!x_sign) { // n > 0
3227 res = 0x00000001; // return +1
3228 } else {
3229 res = 0x8000000000000000ull;
3230 // set invalid flag
3231 *pfpsf |= INVALID_EXCEPTION;
3232 // return Integer Indefinite
3233 res = 0x8000000000000000ull;
3234 BID_RETURN (res);
3236 } else { // 19 <= ind <= 33
3237 if ((C1.w[1] < midpoint128[ind - 19].w[1])
3238 || ((C1.w[1] == midpoint128[ind - 19].w[1])
3239 && (C1.w[0] < midpoint128[ind - 19].w[0]))) {
3240 res = 0x0000000000000000ull; // return 0
3241 } else if (!x_sign) { // n > 0
3242 res = 0x00000001; // return +1
3243 } else {
3244 res = 0x8000000000000000ull;
3245 *pfpsf |= INVALID_EXCEPTION;
3246 // return Integer Indefinite
3247 res = 0x8000000000000000ull;
3248 BID_RETURN (res);
3251 // set inexact flag
3252 *pfpsf |= INEXACT_EXCEPTION;
3253 } else { // if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
3254 // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
3255 // to nearest to a 64-bit unsigned signed integer
3256 if (x_sign) { // x <= -1
3257 // set invalid flag
3258 *pfpsf |= INVALID_EXCEPTION;
3259 // return Integer Indefinite
3260 res = 0x8000000000000000ull;
3261 BID_RETURN (res);
3263 // 1 <= x < 2^64-1/2 so x can be rounded
3264 // to nearest to a 64-bit unsigned integer
3265 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
3266 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x'
3267 // chop off ind digits from the lower part of C1
3268 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
3269 tmp64 = C1.w[0];
3270 if (ind <= 19) {
3271 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
3272 } else {
3273 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
3274 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
3276 if (C1.w[0] < tmp64)
3277 C1.w[1]++;
3278 // calculate C* and f*
3279 // C* is actually floor(C*) in this case
3280 // C* and f* need shifting and masking, as shown by
3281 // shiftright128[] and maskhigh128[]
3282 // 1 <= x <= 33
3283 // kx = 10^(-x) = ten2mk128[ind - 1]
3284 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
3285 // the approximation of 10^(-x) was rounded up to 118 bits
3286 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
3287 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
3288 Cstar.w[1] = P256.w[3];
3289 Cstar.w[0] = P256.w[2];
3290 fstar.w[3] = 0;
3291 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
3292 fstar.w[1] = P256.w[1];
3293 fstar.w[0] = P256.w[0];
3294 } else { // 22 <= ind - 1 <= 33
3295 Cstar.w[1] = 0;
3296 Cstar.w[0] = P256.w[3];
3297 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
3298 fstar.w[2] = P256.w[2];
3299 fstar.w[1] = P256.w[1];
3300 fstar.w[0] = P256.w[0];
3302 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
3303 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
3304 // if (0 < f* < 10^(-x)) then the result is a midpoint
3305 // if floor(C*) is even then C* = floor(C*) - logical right
3306 // shift; C* has p decimal digits, correct by Prop. 1)
3307 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
3308 // shift; C* has p decimal digits, correct by Pr. 1)
3309 // else
3310 // C* = floor(C*) (logical right shift; C has p decimal digits,
3311 // correct by Property 1)
3312 // n = C* * 10^(e+x)
3314 // shift right C* by Ex-128 = shiftright128[ind]
3315 shift = shiftright128[ind - 1]; // 0 <= shift <= 102
3316 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
3317 Cstar.w[0] =
3318 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
3319 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
3320 } else { // 22 <= ind - 1 <= 33
3321 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38
3323 // determine inexactness of the rounding of C*
3324 // if (0 < f* - 1/2 < 10^(-x)) then
3325 // the result is exact
3326 // else // if (f* - 1/2 > T*) then
3327 // the result is inexact
3328 if (ind - 1 <= 2) {
3329 if (fstar.w[1] > 0x8000000000000000ull ||
3330 (fstar.w[1] == 0x8000000000000000ull
3331 && fstar.w[0] > 0x0ull)) {
3332 // f* > 1/2 and the result may be exact
3333 tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2
3334 if (tmp64 > ten2mk128trunc[ind - 1].w[1]
3335 || (tmp64 == ten2mk128trunc[ind - 1].w[1]
3336 && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) {
3337 // set the inexact flag
3338 *pfpsf |= INEXACT_EXCEPTION;
3339 } // else the result is exact
3340 } else { // the result is inexact; f2* <= 1/2
3341 // set the inexact flag
3342 *pfpsf |= INEXACT_EXCEPTION;
3344 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21
3345 if (fstar.w[3] > 0x0 ||
3346 (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) ||
3347 (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] &&
3348 (fstar.w[1] || fstar.w[0]))) {
3349 // f2* > 1/2 and the result may be exact
3350 // Calculate f2* - 1/2
3351 tmp64 = fstar.w[2] - onehalf128[ind - 1];
3352 tmp64A = fstar.w[3];
3353 if (tmp64 > fstar.w[2])
3354 tmp64A--;
3355 if (tmp64A || tmp64
3356 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
3357 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
3358 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
3359 // set the inexact flag
3360 *pfpsf |= INEXACT_EXCEPTION;
3361 } // else the result is exact
3362 } else { // the result is inexact; f2* <= 1/2
3363 // set the inexact flag
3364 *pfpsf |= INEXACT_EXCEPTION;
3366 } else { // if 22 <= ind <= 33
3367 if (fstar.w[3] > onehalf128[ind - 1] ||
3368 (fstar.w[3] == onehalf128[ind - 1] &&
3369 (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
3370 // f2* > 1/2 and the result may be exact
3371 // Calculate f2* - 1/2
3372 tmp64 = fstar.w[3] - onehalf128[ind - 1];
3373 if (tmp64 || fstar.w[2]
3374 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
3375 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
3376 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
3377 // set the inexact flag
3378 *pfpsf |= INEXACT_EXCEPTION;
3379 } // else the result is exact
3380 } else { // the result is inexact; f2* <= 1/2
3381 // set the inexact flag
3382 *pfpsf |= INEXACT_EXCEPTION;
3386 // if the result was a midpoint it was rounded away from zero
3387 res = Cstar.w[0]; // the result is positive
3388 } else if (exp == 0) {
3389 // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
3390 // res = C (exact)
3391 res = C1.w[0];
3392 } else {
3393 // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
3394 // res = C * 10^exp (exact) - must fit in 64 bits
3395 res = C1.w[0] * ten2k64[exp];
3400 BID_RETURN (res);