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
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
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
)
36 int exp
; // unbiased exponent
37 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
40 unsigned int x_nr_bits
;
43 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
53 // check for NaN or Infinity
54 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
59 *pfpsf
|= INVALID_EXCEPTION
;
60 // return Integer Indefinite
61 res
= 0x8000000000000000ull
;
64 *pfpsf
|= INVALID_EXCEPTION
;
65 // return Integer Indefinite
66 res
= 0x8000000000000000ull
;
69 } else { // x is not a NaN, so it must be infinity
70 if (!x_sign
) { // x is +inf
72 *pfpsf
|= INVALID_EXCEPTION
;
73 // return Integer Indefinite
74 res
= 0x8000000000000000ull
;
77 *pfpsf
|= INVALID_EXCEPTION
;
78 // return Integer Indefinite
79 res
= 0x8000000000000000ull
;
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
;
91 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
93 res
= 0x0000000000000000ull
;
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
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
105 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
107 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
109 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
111 } else { // if x < 2^53
112 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
119 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
121 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
129 exp
= (x_exp
>> 49) - 6176;
131 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
133 *pfpsf
|= INVALID_EXCEPTION
;
134 // return Integer Indefinite
135 res
= 0x8000000000000000ull
;
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
150 if (C1
.w
[1] != 0 || C1
.w
[0] > 0x05ull
) {
152 *pfpsf
|= INVALID_EXCEPTION
;
153 // return Integer Indefinite
154 res
= 0x8000000000000000ull
;
157 // else cases that can be rounded to 64-bit unsigned int fall through
158 // to '1 <= q + exp <= 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
165 *pfpsf
|= INVALID_EXCEPTION
;
166 // return Integer Indefinite
167 res
= 0x8000000000000000ull
;
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
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
)) {
182 *pfpsf
|= INVALID_EXCEPTION
;
183 // return Integer Indefinite
184 res
= 0x8000000000000000ull
;
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
)) {
195 *pfpsf
|= INVALID_EXCEPTION
;
196 // return Integer Indefinite
197 res
= 0x8000000000000000ull
;
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])
208 if (C
.w
[1] > 0x01 || (C
.w
[1] == 0x01
209 && C
.w
[0] >= 0xffffffffffffffffull
)) {
211 *pfpsf
|= INVALID_EXCEPTION
;
212 // return Integer Indefinite
213 res
= 0x8000000000000000ull
;
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
)) {
223 *pfpsf
|= INVALID_EXCEPTION
;
224 // return Integer Indefinite
225 res
= 0x8000000000000000ull
;
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
233 C
.w
[0] = 0xfffffffffffffffbull
;
234 __mul_128x64_to_128 (C
, ten2k64
[q
- 21], C
);
236 || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
238 *pfpsf
|= INVALID_EXCEPTION
;
239 // return Integer Indefinite
240 res
= 0x8000000000000000ull
;
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)
252 res
= 0x0000000000000000ull
;
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)
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
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
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
288 *pfpsf
|= INVALID_EXCEPTION
;
289 // return Integer Indefinite
290 res
= 0x8000000000000000ull
;
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
301 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
303 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
304 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].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[]
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];
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
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)
340 // C* = floor(C*) (logical right shift; C has p decimal digits,
341 // correct by Property 1)
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
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
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
];
383 /*****************************************************************************
384 * BID128_to_uint64_xrnint
385 ****************************************************************************/
387 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
388 bid128_to_uint64_xrnint
, x
)
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
;
397 unsigned int x_nr_bits
;
400 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
410 // check for NaN or Infinity
411 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
416 *pfpsf
|= INVALID_EXCEPTION
;
417 // return Integer Indefinite
418 res
= 0x8000000000000000ull
;
419 } else { // x is QNaN
421 *pfpsf
|= INVALID_EXCEPTION
;
422 // return Integer Indefinite
423 res
= 0x8000000000000000ull
;
426 } else { // x is not a NaN, so it must be infinity
427 if (!x_sign
) { // x is +inf
429 *pfpsf
|= INVALID_EXCEPTION
;
430 // return Integer Indefinite
431 res
= 0x8000000000000000ull
;
432 } else { // x is -inf
434 *pfpsf
|= INVALID_EXCEPTION
;
435 // return Integer Indefinite
436 res
= 0x8000000000000000ull
;
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
;
448 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
450 res
= 0x0000000000000000ull
;
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
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
462 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
464 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
466 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
468 } else { // if x < 2^53
469 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
476 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
478 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
486 exp
= (x_exp
>> 49) - 6176;
488 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
490 *pfpsf
|= INVALID_EXCEPTION
;
491 // return Integer Indefinite
492 res
= 0x8000000000000000ull
;
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
507 if (C1
.w
[1] != 0 || C1
.w
[0] > 0x05ull
) {
509 *pfpsf
|= INVALID_EXCEPTION
;
510 // return Integer Indefinite
511 res
= 0x8000000000000000ull
;
514 // else cases that can be rounded to 64-bit unsigned int fall through
515 // to '1 <= q + exp <= 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
522 *pfpsf
|= INVALID_EXCEPTION
;
523 // return Integer Indefinite
524 res
= 0x8000000000000000ull
;
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
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
)) {
539 *pfpsf
|= INVALID_EXCEPTION
;
540 // return Integer Indefinite
541 res
= 0x8000000000000000ull
;
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
)) {
552 *pfpsf
|= INVALID_EXCEPTION
;
553 // return Integer Indefinite
554 res
= 0x8000000000000000ull
;
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])
565 if (C
.w
[1] > 0x01 || (C
.w
[1] == 0x01
566 && C
.w
[0] >= 0xffffffffffffffffull
)) {
568 *pfpsf
|= INVALID_EXCEPTION
;
569 // return Integer Indefinite
570 res
= 0x8000000000000000ull
;
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
)) {
580 *pfpsf
|= INVALID_EXCEPTION
;
581 // return Integer Indefinite
582 res
= 0x8000000000000000ull
;
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
590 C
.w
[0] = 0xfffffffffffffffbull
;
591 __mul_128x64_to_128 (C
, ten2k64
[q
- 21], C
);
593 || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
595 *pfpsf
|= INVALID_EXCEPTION
;
596 // return Integer Indefinite
597 res
= 0x8000000000000000ull
;
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)
609 *pfpsf
|= INEXACT_EXCEPTION
;
611 res
= 0x0000000000000000ull
;
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)
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
627 res
= 0x8000000000000000ull
;
628 *pfpsf
|= INVALID_EXCEPTION
;
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
639 res
= 0x8000000000000000ull
;
640 *pfpsf
|= INVALID_EXCEPTION
;
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
651 *pfpsf
|= INVALID_EXCEPTION
;
652 // return Integer Indefinite
653 res
= 0x8000000000000000ull
;
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
664 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
666 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
667 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].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[]
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];
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
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)
703 // C* = floor(C*) (logical right shift; C has p decimal digits,
704 // correct by Property 1)
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
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
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];
746 if (tmp64
> fstar
.w
[2])
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
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
];
809 /*****************************************************************************
810 * BID128_to_uint64_floor
811 ****************************************************************************/
813 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
814 bid128_to_uint64_floor
, x
)
819 int exp
; // unbiased exponent
820 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
822 unsigned int x_nr_bits
;
825 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
834 // check for NaN or Infinity
835 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
840 *pfpsf
|= INVALID_EXCEPTION
;
841 // return Integer Indefinite
842 res
= 0x8000000000000000ull
;
843 } else { // x is QNaN
845 *pfpsf
|= INVALID_EXCEPTION
;
846 // return Integer Indefinite
847 res
= 0x8000000000000000ull
;
850 } else { // x is not a NaN, so it must be infinity
851 if (!x_sign
) { // x is +inf
853 *pfpsf
|= INVALID_EXCEPTION
;
854 // return Integer Indefinite
855 res
= 0x8000000000000000ull
;
856 } else { // x is -inf
858 *pfpsf
|= INVALID_EXCEPTION
;
859 // return Integer Indefinite
860 res
= 0x8000000000000000ull
;
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
;
872 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
874 res
= 0x0000000000000000ull
;
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
882 *pfpsf
|= INVALID_EXCEPTION
;
883 // return Integer Indefinite
884 res
= 0x8000000000000000ull
;
887 // q = nr. of decimal digits in x
888 // determine first the nr. of bits in x
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
895 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
897 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
899 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
901 } else { // if x < 2^53
902 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
909 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
911 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
919 exp
= (x_exp
>> 49) - 6176;
920 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
922 *pfpsf
|= INVALID_EXCEPTION
;
923 // return Integer Indefinite
924 res
= 0x8000000000000000ull
;
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
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) {
944 *pfpsf
|= INVALID_EXCEPTION
;
945 // return Integer Indefinite
946 res
= 0x8000000000000000ull
;
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) {
957 *pfpsf
|= INVALID_EXCEPTION
;
958 // return Integer Indefinite
959 res
= 0x8000000000000000ull
;
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) {
969 *pfpsf
|= INVALID_EXCEPTION
;
970 // return Integer Indefinite
971 res
= 0x8000000000000000ull
;
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) {
981 *pfpsf
|= INVALID_EXCEPTION
;
982 // return Integer Indefinite
983 res
= 0x8000000000000000ull
;
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
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])) {
995 *pfpsf
|= INVALID_EXCEPTION
;
996 // return Integer Indefinite
997 res
= 0x8000000000000000ull
;
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)
1008 res
= 0x0000000000000000ull
;
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[]
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
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
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
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
];
1064 /*****************************************************************************
1065 * BID128_to_uint64_xfloor
1066 ****************************************************************************/
1068 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
1069 bid128_to_uint64_xfloor
, x
)
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
;
1080 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
1090 // check for NaN or Infinity
1091 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
1096 *pfpsf
|= INVALID_EXCEPTION
;
1097 // return Integer Indefinite
1098 res
= 0x8000000000000000ull
;
1099 } else { // x is QNaN
1101 *pfpsf
|= INVALID_EXCEPTION
;
1102 // return Integer Indefinite
1103 res
= 0x8000000000000000ull
;
1106 } else { // x is not a NaN, so it must be infinity
1107 if (!x_sign
) { // x is +inf
1109 *pfpsf
|= INVALID_EXCEPTION
;
1110 // return Integer Indefinite
1111 res
= 0x8000000000000000ull
;
1112 } else { // x is -inf
1114 *pfpsf
|= INVALID_EXCEPTION
;
1115 // return Integer Indefinite
1116 res
= 0x8000000000000000ull
;
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
;
1128 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1130 res
= 0x0000000000000000ull
;
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
1138 *pfpsf
|= INVALID_EXCEPTION
;
1139 // return Integer Indefinite
1140 res
= 0x8000000000000000ull
;
1143 // q = nr. of decimal digits in x
1144 // determine first the nr. of bits in x
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
1151 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1152 } else { // x < 2^32
1153 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1155 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1157 } else { // if x < 2^53
1158 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
1165 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1167 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
1175 exp
= (x_exp
>> 49) - 6176;
1176 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1178 *pfpsf
|= INVALID_EXCEPTION
;
1179 // return Integer Indefinite
1180 res
= 0x8000000000000000ull
;
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
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) {
1200 *pfpsf
|= INVALID_EXCEPTION
;
1201 // return Integer Indefinite
1202 res
= 0x8000000000000000ull
;
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) {
1213 *pfpsf
|= INVALID_EXCEPTION
;
1214 // return Integer Indefinite
1215 res
= 0x8000000000000000ull
;
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) {
1225 *pfpsf
|= INVALID_EXCEPTION
;
1226 // return Integer Indefinite
1227 res
= 0x8000000000000000ull
;
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) {
1237 *pfpsf
|= INVALID_EXCEPTION
;
1238 // return Integer Indefinite
1239 res
= 0x8000000000000000ull
;
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
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])) {
1251 *pfpsf
|= INVALID_EXCEPTION
;
1252 // return Integer Indefinite
1253 res
= 0x8000000000000000ull
;
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)
1264 *pfpsf
|= INEXACT_EXCEPTION
;
1266 res
= 0x0000000000000000ull
;
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[]
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];
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
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
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
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
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
];
1359 /*****************************************************************************
1360 * BID128_to_uint64_ceil
1361 ****************************************************************************/
1363 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
, bid128_to_uint64_ceil
,
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
;
1375 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
1385 // check for NaN or Infinity
1386 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
1391 *pfpsf
|= INVALID_EXCEPTION
;
1392 // return Integer Indefinite
1393 res
= 0x8000000000000000ull
;
1394 } else { // x is QNaN
1396 *pfpsf
|= INVALID_EXCEPTION
;
1397 // return Integer Indefinite
1398 res
= 0x8000000000000000ull
;
1401 } else { // x is not a NaN, so it must be infinity
1402 if (!x_sign
) { // x is +inf
1404 *pfpsf
|= INVALID_EXCEPTION
;
1405 // return Integer Indefinite
1406 res
= 0x8000000000000000ull
;
1407 } else { // x is -inf
1409 *pfpsf
|= INVALID_EXCEPTION
;
1410 // return Integer Indefinite
1411 res
= 0x8000000000000000ull
;
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
;
1423 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1425 res
= 0x0000000000000000ull
;
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
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
1437 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1438 } else { // x < 2^32
1439 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1441 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1443 } else { // if x < 2^53
1444 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
1451 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1453 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
1461 exp
= (x_exp
>> 49) - 6176;
1462 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1464 *pfpsf
|= INVALID_EXCEPTION
;
1465 // return Integer Indefinite
1466 res
= 0x8000000000000000ull
;
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
1481 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x0aull
) {
1483 *pfpsf
|= INVALID_EXCEPTION
;
1484 // return Integer Indefinite
1485 res
= 0x8000000000000000ull
;
1488 // else cases that can be rounded to 64-bit unsigned int fall through
1489 // to '1 <= q + exp <= 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
1496 *pfpsf
|= INVALID_EXCEPTION
;
1497 // return Integer Indefinite
1498 res
= 0x8000000000000000ull
;
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
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
)) {
1513 *pfpsf
|= INVALID_EXCEPTION
;
1514 // return Integer Indefinite
1515 res
= 0x8000000000000000ull
;
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
)) {
1526 *pfpsf
|= INVALID_EXCEPTION
;
1527 // return Integer Indefinite
1528 res
= 0x8000000000000000ull
;
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
1537 *pfpsf
|= INVALID_EXCEPTION
;
1538 // return Integer Indefinite
1539 res
= 0x8000000000000000ull
;
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
)) {
1549 *pfpsf
|= INVALID_EXCEPTION
;
1550 // return Integer Indefinite
1551 res
= 0x8000000000000000ull
;
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
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])) {
1563 *pfpsf
|= INVALID_EXCEPTION
;
1564 // return Integer Indefinite
1565 res
= 0x8000000000000000ull
;
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)
1578 res
= 0x0000000000000000ull
;
1580 res
= 0x0000000000000001ull
;
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
1587 *pfpsf
|= INVALID_EXCEPTION
;
1588 // return Integer Indefinite
1589 res
= 0x8000000000000000ull
;
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[]
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];
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
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
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
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
1650 if (Cstar
.w
[0] == 0x0)
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
1660 if (Cstar
.w
[0] == 0x0)
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
1671 if (Cstar
.w
[0] == 0x0)
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
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
];
1693 /*****************************************************************************
1694 * BID128_to_uint64_xceil
1695 ****************************************************************************/
1697 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
1698 bid128_to_uint64_xceil
, x
)
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
;
1709 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
1719 // check for NaN or Infinity
1720 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
1725 *pfpsf
|= INVALID_EXCEPTION
;
1726 // return Integer Indefinite
1727 res
= 0x8000000000000000ull
;
1728 } else { // x is QNaN
1730 *pfpsf
|= INVALID_EXCEPTION
;
1731 // return Integer Indefinite
1732 res
= 0x8000000000000000ull
;
1735 } else { // x is not a NaN, so it must be infinity
1736 if (!x_sign
) { // x is +inf
1738 *pfpsf
|= INVALID_EXCEPTION
;
1739 // return Integer Indefinite
1740 res
= 0x8000000000000000ull
;
1741 } else { // x is -inf
1743 *pfpsf
|= INVALID_EXCEPTION
;
1744 // return Integer Indefinite
1745 res
= 0x8000000000000000ull
;
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
;
1757 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1759 res
= 0x0000000000000000ull
;
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
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
1771 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1772 } else { // x < 2^32
1773 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1775 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1777 } else { // if x < 2^53
1778 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
1785 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1787 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
1795 exp
= (x_exp
>> 49) - 6176;
1796 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
1798 *pfpsf
|= INVALID_EXCEPTION
;
1799 // return Integer Indefinite
1800 res
= 0x8000000000000000ull
;
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
1815 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x0aull
) {
1817 *pfpsf
|= INVALID_EXCEPTION
;
1818 // return Integer Indefinite
1819 res
= 0x8000000000000000ull
;
1822 // else cases that can be rounded to 64-bit unsigned int fall through
1823 // to '1 <= q + exp <= 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
1830 *pfpsf
|= INVALID_EXCEPTION
;
1831 // return Integer Indefinite
1832 res
= 0x8000000000000000ull
;
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
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
)) {
1847 *pfpsf
|= INVALID_EXCEPTION
;
1848 // return Integer Indefinite
1849 res
= 0x8000000000000000ull
;
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
)) {
1860 *pfpsf
|= INVALID_EXCEPTION
;
1861 // return Integer Indefinite
1862 res
= 0x8000000000000000ull
;
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
1871 *pfpsf
|= INVALID_EXCEPTION
;
1872 // return Integer Indefinite
1873 res
= 0x8000000000000000ull
;
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
)) {
1883 *pfpsf
|= INVALID_EXCEPTION
;
1884 // return Integer Indefinite
1885 res
= 0x8000000000000000ull
;
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
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])) {
1897 *pfpsf
|= INVALID_EXCEPTION
;
1898 // return Integer Indefinite
1899 res
= 0x8000000000000000ull
;
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)
1911 *pfpsf
|= INEXACT_EXCEPTION
;
1914 res
= 0x0000000000000000ull
;
1916 res
= 0x0000000000000001ull
;
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
1923 *pfpsf
|= INVALID_EXCEPTION
;
1924 // return Integer Indefinite
1925 res
= 0x8000000000000000ull
;
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[]
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];
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
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
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
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
1986 if (Cstar
.w
[0] == 0x0)
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
1998 if (Cstar
.w
[0] == 0x0)
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
2011 if (Cstar
.w
[0] == 0x0)
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
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
];
2035 /*****************************************************************************
2036 * BID128_to_uint64_int
2037 ****************************************************************************/
2039 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
, bid128_to_uint64_int
,
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
;
2051 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
2060 // check for NaN or Infinity
2061 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
2066 *pfpsf
|= INVALID_EXCEPTION
;
2067 // return Integer Indefinite
2068 res
= 0x8000000000000000ull
;
2069 } else { // x is QNaN
2071 *pfpsf
|= INVALID_EXCEPTION
;
2072 // return Integer Indefinite
2073 res
= 0x8000000000000000ull
;
2076 } else { // x is not a NaN, so it must be infinity
2077 if (!x_sign
) { // x is +inf
2079 *pfpsf
|= INVALID_EXCEPTION
;
2080 // return Integer Indefinite
2081 res
= 0x8000000000000000ull
;
2082 } else { // x is -inf
2084 *pfpsf
|= INVALID_EXCEPTION
;
2085 // return Integer Indefinite
2086 res
= 0x8000000000000000ull
;
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
;
2098 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
2100 res
= 0x0000000000000000ull
;
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
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
2112 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2113 } else { // x < 2^32
2114 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
2116 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2118 } else { // if x < 2^53
2119 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
2126 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2128 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
2136 exp
= (x_exp
>> 49) - 6176;
2138 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2140 *pfpsf
|= INVALID_EXCEPTION
;
2141 // return Integer Indefinite
2142 res
= 0x8000000000000000ull
;
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
2157 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x0aull
) {
2159 *pfpsf
|= INVALID_EXCEPTION
;
2160 // return Integer Indefinite
2161 res
= 0x8000000000000000ull
;
2164 // else cases that can be rounded to 64-bit unsigned int fall through
2165 // to '1 <= q + exp <= 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
2172 *pfpsf
|= INVALID_EXCEPTION
;
2173 // return Integer Indefinite
2174 res
= 0x8000000000000000ull
;
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
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) {
2189 *pfpsf
|= INVALID_EXCEPTION
;
2190 // return Integer Indefinite
2191 res
= 0x8000000000000000ull
;
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) {
2202 *pfpsf
|= INVALID_EXCEPTION
;
2203 // return Integer Indefinite
2204 res
= 0x8000000000000000ull
;
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) {
2214 *pfpsf
|= INVALID_EXCEPTION
;
2215 // return Integer Indefinite
2216 res
= 0x8000000000000000ull
;
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) {
2226 *pfpsf
|= INVALID_EXCEPTION
;
2227 // return Integer Indefinite
2228 res
= 0x8000000000000000ull
;
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
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])) {
2241 *pfpsf
|= INVALID_EXCEPTION
;
2242 // return Integer Indefinite
2243 res
= 0x8000000000000000ull
;
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)
2255 res
= 0x0000000000000000ull
;
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
2262 *pfpsf
|= INVALID_EXCEPTION
;
2263 // return Integer Indefinite
2264 res
= 0x8000000000000000ull
;
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[]
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
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
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
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
];
2320 /*****************************************************************************
2321 * BID128_to_uint64_xint
2322 ****************************************************************************/
2324 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
, bid128_to_uint64_xint
,
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
;
2336 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
2346 // check for NaN or Infinity
2347 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
2352 *pfpsf
|= INVALID_EXCEPTION
;
2353 // return Integer Indefinite
2354 res
= 0x8000000000000000ull
;
2355 } else { // x is QNaN
2357 *pfpsf
|= INVALID_EXCEPTION
;
2358 // return Integer Indefinite
2359 res
= 0x8000000000000000ull
;
2362 } else { // x is not a NaN, so it must be infinity
2363 if (!x_sign
) { // x is +inf
2365 *pfpsf
|= INVALID_EXCEPTION
;
2366 // return Integer Indefinite
2367 res
= 0x8000000000000000ull
;
2368 } else { // x is -inf
2370 *pfpsf
|= INVALID_EXCEPTION
;
2371 // return Integer Indefinite
2372 res
= 0x8000000000000000ull
;
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
;
2384 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
2386 res
= 0x0000000000000000ull
;
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
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
2398 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2399 } else { // x < 2^32
2400 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
2402 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2404 } else { // if x < 2^53
2405 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
2412 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2414 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
2422 exp
= (x_exp
>> 49) - 6176;
2423 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2425 *pfpsf
|= INVALID_EXCEPTION
;
2426 // return Integer Indefinite
2427 res
= 0x8000000000000000ull
;
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
2442 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x0aull
) {
2444 *pfpsf
|= INVALID_EXCEPTION
;
2445 // return Integer Indefinite
2446 res
= 0x8000000000000000ull
;
2449 // else cases that can be rounded to 64-bit unsigned int fall through
2450 // to '1 <= q + exp <= 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
2457 *pfpsf
|= INVALID_EXCEPTION
;
2458 // return Integer Indefinite
2459 res
= 0x8000000000000000ull
;
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
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) {
2474 *pfpsf
|= INVALID_EXCEPTION
;
2475 // return Integer Indefinite
2476 res
= 0x8000000000000000ull
;
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) {
2487 *pfpsf
|= INVALID_EXCEPTION
;
2488 // return Integer Indefinite
2489 res
= 0x8000000000000000ull
;
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) {
2499 *pfpsf
|= INVALID_EXCEPTION
;
2500 // return Integer Indefinite
2501 res
= 0x8000000000000000ull
;
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) {
2511 *pfpsf
|= INVALID_EXCEPTION
;
2512 // return Integer Indefinite
2513 res
= 0x8000000000000000ull
;
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
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])) {
2526 *pfpsf
|= INVALID_EXCEPTION
;
2527 // return Integer Indefinite
2528 res
= 0x8000000000000000ull
;
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)
2540 *pfpsf
|= INEXACT_EXCEPTION
;
2542 res
= 0x0000000000000000ull
;
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
2549 *pfpsf
|= INVALID_EXCEPTION
;
2550 // return Integer Indefinite
2551 res
= 0x8000000000000000ull
;
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[]
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];
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
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
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
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
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
];
2644 /*****************************************************************************
2645 * BID128_to_uint64_rninta
2646 ****************************************************************************/
2648 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
2649 bid128_to_uint64_rninta
, x
)
2654 int exp
; // unbiased exponent
2655 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2657 BID_UI64DOUBLE tmp1
;
2658 unsigned int x_nr_bits
;
2661 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
2670 // check for NaN or Infinity
2671 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
2676 *pfpsf
|= INVALID_EXCEPTION
;
2677 // return Integer Indefinite
2678 res
= 0x8000000000000000ull
;
2679 } else { // x is QNaN
2681 *pfpsf
|= INVALID_EXCEPTION
;
2682 // return Integer Indefinite
2683 res
= 0x8000000000000000ull
;
2686 } else { // x is not a NaN, so it must be infinity
2687 if (!x_sign
) { // x is +inf
2689 *pfpsf
|= INVALID_EXCEPTION
;
2690 // return Integer Indefinite
2691 res
= 0x8000000000000000ull
;
2692 } else { // x is -inf
2694 *pfpsf
|= INVALID_EXCEPTION
;
2695 // return Integer Indefinite
2696 res
= 0x8000000000000000ull
;
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
;
2708 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
2710 res
= 0x0000000000000000ull
;
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
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
2722 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2723 } else { // x < 2^32
2724 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
2726 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2728 } else { // if x < 2^53
2729 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
2736 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2738 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
2746 exp
= (x_exp
>> 49) - 6176;
2747 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
2749 *pfpsf
|= INVALID_EXCEPTION
;
2750 // return Integer Indefinite
2751 res
= 0x8000000000000000ull
;
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
2766 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x05ull
) {
2768 *pfpsf
|= INVALID_EXCEPTION
;
2769 // return Integer Indefinite
2770 res
= 0x8000000000000000ull
;
2773 // else cases that can be rounded to 64-bit unsigned int fall through
2774 // to '1 <= q + exp <= 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
2781 *pfpsf
|= INVALID_EXCEPTION
;
2782 // return Integer Indefinite
2783 res
= 0x8000000000000000ull
;
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
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
)) {
2798 *pfpsf
|= INVALID_EXCEPTION
;
2799 // return Integer Indefinite
2800 res
= 0x8000000000000000ull
;
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
)) {
2811 *pfpsf
|= INVALID_EXCEPTION
;
2812 // return Integer Indefinite
2813 res
= 0x8000000000000000ull
;
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])
2824 if (C
.w
[1] > 0x01 || (C
.w
[1] == 0x01
2825 && C
.w
[0] >= 0xffffffffffffffffull
)) {
2827 *pfpsf
|= INVALID_EXCEPTION
;
2828 // return Integer Indefinite
2829 res
= 0x8000000000000000ull
;
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
)) {
2839 *pfpsf
|= INVALID_EXCEPTION
;
2840 // return Integer Indefinite
2841 res
= 0x8000000000000000ull
;
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
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])) {
2854 *pfpsf
|= INVALID_EXCEPTION
;
2855 // return Integer Indefinite
2856 res
= 0x8000000000000000ull
;
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)
2868 res
= 0x0000000000000000ull
;
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)
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
2885 *pfpsf
|= INVALID_EXCEPTION
;
2886 // return Integer Indefinite
2887 res
= 0x8000000000000000ull
;
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
2899 *pfpsf
|= INVALID_EXCEPTION
;
2900 // return Integer Indefinite
2901 res
= 0x8000000000000000ull
;
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
2910 *pfpsf
|= INVALID_EXCEPTION
;
2911 // return Integer Indefinite
2912 res
= 0x8000000000000000ull
;
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
2923 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
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
)
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[]
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
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)
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
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
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
];
2985 /*****************************************************************************
2986 * BID128_to_uint64_xrninta
2987 ****************************************************************************/
2989 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64
,
2990 bid128_to_uint64_xrninta
, x
)
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
;
3002 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
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
;
3012 // check for NaN or Infinity
3013 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_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
3018 *pfpsf
|= INVALID_EXCEPTION
;
3019 // return Integer Indefinite
3020 res
= 0x8000000000000000ull
;
3021 } else { // x is QNaN
3023 *pfpsf
|= INVALID_EXCEPTION
;
3024 // return Integer Indefinite
3025 res
= 0x8000000000000000ull
;
3028 } else { // x is not a NaN, so it must be infinity
3029 if (!x_sign
) { // x is +inf
3031 *pfpsf
|= INVALID_EXCEPTION
;
3032 // return Integer Indefinite
3033 res
= 0x8000000000000000ull
;
3034 } else { // x is -inf
3036 *pfpsf
|= INVALID_EXCEPTION
;
3037 // return Integer Indefinite
3038 res
= 0x8000000000000000ull
;
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
;
3050 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
3052 res
= 0x0000000000000000ull
;
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
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
3064 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
3065 } else { // x < 2^32
3066 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
3068 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
3070 } else { // if x < 2^53
3071 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
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
3078 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
3080 q
= nr_digits
[x_nr_bits
- 1].digits
;
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
))
3088 exp
= (x_exp
>> 49) - 6176;
3090 if ((q
+ exp
) > 20) { // x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
3092 *pfpsf
|= INVALID_EXCEPTION
;
3093 // return Integer Indefinite
3094 res
= 0x8000000000000000ull
;
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
3109 if (C1
.w
[1] != 0 || C1
.w
[0] >= 0x05ull
) {
3111 *pfpsf
|= INVALID_EXCEPTION
;
3112 // return Integer Indefinite
3113 res
= 0x8000000000000000ull
;
3116 // else cases that can be rounded to 64-bit unsigned int fall through
3117 // to '1 <= q + exp <= 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
3124 *pfpsf
|= INVALID_EXCEPTION
;
3125 // return Integer Indefinite
3126 res
= 0x8000000000000000ull
;
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
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
)) {
3141 *pfpsf
|= INVALID_EXCEPTION
;
3142 // return Integer Indefinite
3143 res
= 0x8000000000000000ull
;
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
)) {
3154 *pfpsf
|= INVALID_EXCEPTION
;
3155 // return Integer Indefinite
3156 res
= 0x8000000000000000ull
;
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])
3167 if (C
.w
[1] > 0x01 || (C
.w
[1] == 0x01
3168 && C
.w
[0] >= 0xffffffffffffffffull
)) {
3170 *pfpsf
|= INVALID_EXCEPTION
;
3171 // return Integer Indefinite
3172 res
= 0x8000000000000000ull
;
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
)) {
3182 *pfpsf
|= INVALID_EXCEPTION
;
3183 // return Integer Indefinite
3184 res
= 0x8000000000000000ull
;
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
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])) {
3197 *pfpsf
|= INVALID_EXCEPTION
;
3198 // return Integer Indefinite
3199 res
= 0x8000000000000000ull
;
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)
3211 *pfpsf
|= INEXACT_EXCEPTION
;
3213 res
= 0x0000000000000000ull
;
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)
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
3229 res
= 0x8000000000000000ull
;
3231 *pfpsf
|= INVALID_EXCEPTION
;
3232 // return Integer Indefinite
3233 res
= 0x8000000000000000ull
;
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
3244 res
= 0x8000000000000000ull
;
3245 *pfpsf
|= INVALID_EXCEPTION
;
3246 // return Integer Indefinite
3247 res
= 0x8000000000000000ull
;
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
3258 *pfpsf
|= INVALID_EXCEPTION
;
3259 // return Integer Indefinite
3260 res
= 0x8000000000000000ull
;
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
3271 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
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
)
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[]
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];
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
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)
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
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
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])
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
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
];