1 /* Copyright (C) 2007-2016 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_int64_rnint
28 ****************************************************************************/
30 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_rnint
,
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;
130 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
132 *pfpsf
|= INVALID_EXCEPTION
;
133 // return Integer Indefinite
134 res
= 0x8000000000000000ull
;
136 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
137 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
138 // so x rounded to an integer may or may not fit in a signed 64-bit int
139 // the cases that do not fit are identified here; the ones that fit
140 // fall through and will be handled with other cases further,
141 // under '1 <= q + exp <= 19'
142 if (x_sign
) { // if n < 0 and q + exp = 19
143 // if n < -2^63 - 1/2 then n is too large
144 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
145 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=34
146 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=34
147 C
.w
[1] = 0x0000000000000005ull
;
148 C
.w
[0] = 0000000000000005ull;
149 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
150 // 10^(20-q) is 64-bit, and so is C1
151 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
152 } else if (q
== 20) {
154 } else { // if 21 <= q <= 34
155 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
157 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
159 *pfpsf
|= INVALID_EXCEPTION
;
160 // return Integer Indefinite
161 res
= 0x8000000000000000ull
;
164 // else cases that can be rounded to a 64-bit int fall through
165 // to '1 <= q + exp <= 19'
166 } else { // if n > 0 and q + exp = 19
167 // if n >= 2^63 - 1/2 then n is too large
168 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
169 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34
170 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34
171 C
.w
[1] = 0x0000000000000004ull
;
172 C
.w
[0] = 0xfffffffffffffffbull
;
173 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
174 // 10^(20-q) is 64-bit, and so is C1
175 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
176 } else if (q
== 20) {
178 } else { // if 21 <= q <= 34
179 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
181 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
183 *pfpsf
|= INVALID_EXCEPTION
;
184 // return Integer Indefinite
185 res
= 0x8000000000000000ull
;
188 // else cases that can be rounded to a 64-bit int fall through
189 // to '1 <= q + exp <= 19'
192 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
193 // Note: some of the cases tested for above fall through to this point
194 // Restore C1 which may have been modified above
195 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
197 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
199 res
= 0x0000000000000000ull
;
201 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
202 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
207 if (ind
<= 18) { // 0 <= ind <= 18
208 if ((C1
.w
[1] == 0) && (C1
.w
[0] <= midpoint64
[ind
])) {
209 res
= 0x0000000000000000ull
; // return 0
210 } else if (x_sign
) { // n < 0
211 res
= 0xffffffffffffffffull
; // return -1
213 res
= 0x0000000000000001ull
; // return +1
215 } else { // 19 <= ind <= 33
216 if ((C1
.w
[1] < midpoint128
[ind
- 19].w
[1])
217 || ((C1
.w
[1] == midpoint128
[ind
- 19].w
[1])
218 && (C1
.w
[0] <= midpoint128
[ind
- 19].w
[0]))) {
219 res
= 0x0000000000000000ull
; // return 0
220 } else if (x_sign
) { // n < 0
221 res
= 0xffffffffffffffffull
; // return -1
223 res
= 0x0000000000000001ull
; // return +1
226 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
227 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
228 // to nearest to a 64-bit signed integer
229 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
230 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
231 // chop off ind digits from the lower part of C1
232 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
235 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
237 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
238 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].w
[1];
242 // calculate C* and f*
243 // C* is actually floor(C*) in this case
244 // C* and f* need shifting and masking, as shown by
245 // shiftright128[] and maskhigh128[]
247 // kx = 10^(-x) = ten2mk128[ind - 1]
248 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
249 // the approximation of 10^(-x) was rounded up to 118 bits
250 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
251 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
252 Cstar
.w
[1] = P256
.w
[3];
253 Cstar
.w
[0] = P256
.w
[2];
255 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
256 fstar
.w
[1] = P256
.w
[1];
257 fstar
.w
[0] = P256
.w
[0];
258 } else { // 22 <= ind - 1 <= 33
260 Cstar
.w
[0] = P256
.w
[3];
261 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
262 fstar
.w
[2] = P256
.w
[2];
263 fstar
.w
[1] = P256
.w
[1];
264 fstar
.w
[0] = P256
.w
[0];
266 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
267 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
268 // if (0 < f* < 10^(-x)) then the result is a midpoint
269 // if floor(C*) is even then C* = floor(C*) - logical right
270 // shift; C* has p decimal digits, correct by Prop. 1)
271 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
272 // shift; C* has p decimal digits, correct by Pr. 1)
274 // C* = floor(C*) (logical right shift; C has p decimal digits,
275 // correct by Property 1)
278 // shift right C* by Ex-128 = shiftright128[ind]
279 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
280 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
282 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
283 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
284 } else { // 22 <= ind - 1 <= 33
285 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
287 // if the result was a midpoint it was rounded away from zero, so
288 // it will need a correction
289 // check for midpoints
290 if ((fstar
.w
[3] == 0) && (fstar
.w
[2] == 0) &&
291 (fstar
.w
[1] || fstar
.w
[0]) &&
292 (fstar
.w
[1] < ten2mk128trunc
[ind
- 1].w
[1] ||
293 (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1] &&
294 fstar
.w
[0] <= ten2mk128trunc
[ind
- 1].w
[0]))) {
295 // the result is a midpoint; round to nearest
296 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
297 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
298 Cstar
.w
[0]--; // Cstar.w[0] is now even
299 } // else MP in [ODD, EVEN]
305 } else if (exp
== 0) {
307 // res = +/-C (exact)
312 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
313 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
315 res
= -C1
.w
[0] * ten2k64
[exp
];
317 res
= C1
.w
[0] * ten2k64
[exp
];
325 /*****************************************************************************
326 * BID128_to_int64_xrnint
327 ****************************************************************************/
329 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
,
330 bid128_to_int64_xrnint
, x
)
335 int exp
; // unbiased exponent
336 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
337 UINT64 tmp64
, tmp64A
;
339 unsigned int x_nr_bits
;
342 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
347 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
348 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
349 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
352 // check for NaN or Infinity
353 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
355 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
356 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
358 *pfpsf
|= INVALID_EXCEPTION
;
359 // return Integer Indefinite
360 res
= 0x8000000000000000ull
;
361 } else { // x is QNaN
363 *pfpsf
|= INVALID_EXCEPTION
;
364 // return Integer Indefinite
365 res
= 0x8000000000000000ull
;
368 } else { // x is not a NaN, so it must be infinity
369 if (!x_sign
) { // x is +inf
371 *pfpsf
|= INVALID_EXCEPTION
;
372 // return Integer Indefinite
373 res
= 0x8000000000000000ull
;
374 } else { // x is -inf
376 *pfpsf
|= INVALID_EXCEPTION
;
377 // return Integer Indefinite
378 res
= 0x8000000000000000ull
;
383 // check for non-canonical values (after the check for special values)
384 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
385 || (C1
.w
[1] == 0x0001ed09bead87c0ull
386 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
387 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
388 res
= 0x0000000000000000ull
;
390 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
392 res
= 0x0000000000000000ull
;
394 } else { // x is not special and is not zero
396 // q = nr. of decimal digits in x
397 // determine first the nr. of bits in x
399 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
400 // split the 64-bit value in two 32-bit halves to avoid rounding errors
401 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
402 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
404 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
406 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
408 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
410 } else { // if x < 2^53
411 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
413 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
415 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
416 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
418 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
420 q
= nr_digits
[x_nr_bits
- 1].digits
;
422 q
= nr_digits
[x_nr_bits
- 1].digits1
;
423 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
424 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
425 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
428 exp
= (x_exp
>> 49) - 6176;
429 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
431 *pfpsf
|= INVALID_EXCEPTION
;
432 // return Integer Indefinite
433 res
= 0x8000000000000000ull
;
435 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
436 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
437 // so x rounded to an integer may or may not fit in a signed 64-bit int
438 // the cases that do not fit are identified here; the ones that fit
439 // fall through and will be handled with other cases further,
440 // under '1 <= q + exp <= 19'
441 if (x_sign
) { // if n < 0 and q + exp = 19
442 // if n < -2^63 - 1/2 then n is too large
443 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
444 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=34
445 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=34
446 C
.w
[1] = 0x0000000000000005ull
;
447 C
.w
[0] = 0000000000000005ull;
448 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
449 // 10^(20-q) is 64-bit, and so is C1
450 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
451 } else if (q
== 20) {
453 } else { // if 21 <= q <= 34
454 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
456 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
458 *pfpsf
|= INVALID_EXCEPTION
;
459 // return Integer Indefinite
460 res
= 0x8000000000000000ull
;
463 // else cases that can be rounded to a 64-bit int fall through
464 // to '1 <= q + exp <= 19'
465 } else { // if n > 0 and q + exp = 19
466 // if n >= 2^63 - 1/2 then n is too large
467 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
468 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34
469 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34
470 C
.w
[1] = 0x0000000000000004ull
;
471 C
.w
[0] = 0xfffffffffffffffbull
;
472 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
473 // 10^(20-q) is 64-bit, and so is C1
474 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
475 } else if (q
== 20) {
477 } else { // if 21 <= q <= 34
478 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
480 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
482 *pfpsf
|= INVALID_EXCEPTION
;
483 // return Integer Indefinite
484 res
= 0x8000000000000000ull
;
487 // else cases that can be rounded to a 64-bit int fall through
488 // to '1 <= q + exp <= 19'
491 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
492 // Note: some of the cases tested for above fall through to this point
493 // Restore C1 which may have been modified above
494 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
496 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
498 *pfpsf
|= INEXACT_EXCEPTION
;
500 res
= 0x0000000000000000ull
;
502 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
503 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
508 if (ind
<= 18) { // 0 <= ind <= 18
509 if ((C1
.w
[1] == 0) && (C1
.w
[0] <= midpoint64
[ind
])) {
510 res
= 0x0000000000000000ull
; // return 0
511 } else if (x_sign
) { // n < 0
512 res
= 0xffffffffffffffffull
; // return -1
514 res
= 0x0000000000000001ull
; // return +1
516 } else { // 19 <= ind <= 33
517 if ((C1
.w
[1] < midpoint128
[ind
- 19].w
[1])
518 || ((C1
.w
[1] == midpoint128
[ind
- 19].w
[1])
519 && (C1
.w
[0] <= midpoint128
[ind
- 19].w
[0]))) {
520 res
= 0x0000000000000000ull
; // return 0
521 } else if (x_sign
) { // n < 0
522 res
= 0xffffffffffffffffull
; // return -1
524 res
= 0x0000000000000001ull
; // return +1
528 *pfpsf
|= INEXACT_EXCEPTION
;
529 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
530 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
531 // to nearest to a 64-bit signed integer
532 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
533 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
534 // chop off ind digits from the lower part of C1
535 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
538 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
540 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
541 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].w
[1];
545 // calculate C* and f*
546 // C* is actually floor(C*) in this case
547 // C* and f* need shifting and masking, as shown by
548 // shiftright128[] and maskhigh128[]
550 // kx = 10^(-x) = ten2mk128[ind - 1]
551 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
552 // the approximation of 10^(-x) was rounded up to 118 bits
553 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
554 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
555 Cstar
.w
[1] = P256
.w
[3];
556 Cstar
.w
[0] = P256
.w
[2];
558 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
559 fstar
.w
[1] = P256
.w
[1];
560 fstar
.w
[0] = P256
.w
[0];
561 } else { // 22 <= ind - 1 <= 33
563 Cstar
.w
[0] = P256
.w
[3];
564 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
565 fstar
.w
[2] = P256
.w
[2];
566 fstar
.w
[1] = P256
.w
[1];
567 fstar
.w
[0] = P256
.w
[0];
569 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
570 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
571 // if (0 < f* < 10^(-x)) then the result is a midpoint
572 // if floor(C*) is even then C* = floor(C*) - logical right
573 // shift; C* has p decimal digits, correct by Prop. 1)
574 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
575 // shift; C* has p decimal digits, correct by Pr. 1)
577 // C* = floor(C*) (logical right shift; C has p decimal digits,
578 // correct by Property 1)
581 // shift right C* by Ex-128 = shiftright128[ind]
582 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
583 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
585 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
586 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
587 } else { // 22 <= ind - 1 <= 33
588 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
590 // determine inexactness of the rounding of C*
591 // if (0 < f* - 1/2 < 10^(-x)) then
592 // the result is exact
593 // else // if (f* - 1/2 > T*) then
594 // the result is inexact
596 if (fstar
.w
[1] > 0x8000000000000000ull
||
597 (fstar
.w
[1] == 0x8000000000000000ull
598 && fstar
.w
[0] > 0x0ull
)) {
599 // f* > 1/2 and the result may be exact
600 tmp64
= fstar
.w
[1] - 0x8000000000000000ull
; // f* - 1/2
601 if (tmp64
> ten2mk128trunc
[ind
- 1].w
[1]
602 || (tmp64
== ten2mk128trunc
[ind
- 1].w
[1]
603 && fstar
.w
[0] >= ten2mk128trunc
[ind
- 1].w
[0])) {
604 // set the inexact flag
605 *pfpsf
|= INEXACT_EXCEPTION
;
606 } // else the result is exact
607 } else { // the result is inexact; f2* <= 1/2
608 // set the inexact flag
609 *pfpsf
|= INEXACT_EXCEPTION
;
611 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
612 if (fstar
.w
[3] > 0x0 ||
613 (fstar
.w
[3] == 0x0 && fstar
.w
[2] > onehalf128
[ind
- 1]) ||
614 (fstar
.w
[3] == 0x0 && fstar
.w
[2] == onehalf128
[ind
- 1] &&
615 (fstar
.w
[1] || fstar
.w
[0]))) {
616 // f2* > 1/2 and the result may be exact
617 // Calculate f2* - 1/2
618 tmp64
= fstar
.w
[2] - onehalf128
[ind
- 1];
620 if (tmp64
> fstar
.w
[2])
623 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
624 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
625 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
626 // set the inexact flag
627 *pfpsf
|= INEXACT_EXCEPTION
;
628 } // else the result is exact
629 } else { // the result is inexact; f2* <= 1/2
630 // set the inexact flag
631 *pfpsf
|= INEXACT_EXCEPTION
;
633 } else { // if 22 <= ind <= 33
634 if (fstar
.w
[3] > onehalf128
[ind
- 1] ||
635 (fstar
.w
[3] == onehalf128
[ind
- 1] &&
636 (fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0]))) {
637 // f2* > 1/2 and the result may be exact
638 // Calculate f2* - 1/2
639 tmp64
= fstar
.w
[3] - onehalf128
[ind
- 1];
640 if (tmp64
|| fstar
.w
[2]
641 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
642 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
643 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
644 // set the inexact flag
645 *pfpsf
|= INEXACT_EXCEPTION
;
646 } // else the result is exact
647 } else { // the result is inexact; f2* <= 1/2
648 // set the inexact flag
649 *pfpsf
|= INEXACT_EXCEPTION
;
653 // if the result was a midpoint it was rounded away from zero, so
654 // it will need a correction
655 // check for midpoints
656 if ((fstar
.w
[3] == 0) && (fstar
.w
[2] == 0) &&
657 (fstar
.w
[1] || fstar
.w
[0]) &&
658 (fstar
.w
[1] < ten2mk128trunc
[ind
- 1].w
[1] ||
659 (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1] &&
660 fstar
.w
[0] <= ten2mk128trunc
[ind
- 1].w
[0]))) {
661 // the result is a midpoint; round to nearest
662 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
663 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
664 Cstar
.w
[0]--; // Cstar.w[0] is now even
665 } // else MP in [ODD, EVEN]
671 } else if (exp
== 0) {
673 // res = +/-C (exact)
678 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
679 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
681 res
= -C1
.w
[0] * ten2k64
[exp
];
683 res
= C1
.w
[0] * ten2k64
[exp
];
691 /*****************************************************************************
692 * BID128_to_int64_floor
693 ****************************************************************************/
695 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_floor
,
701 int exp
; // unbiased exponent
702 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
704 unsigned int x_nr_bits
;
707 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
712 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
713 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
714 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
717 // check for NaN or Infinity
718 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
720 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
721 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
723 *pfpsf
|= INVALID_EXCEPTION
;
724 // return Integer Indefinite
725 res
= 0x8000000000000000ull
;
726 } else { // x is QNaN
728 *pfpsf
|= INVALID_EXCEPTION
;
729 // return Integer Indefinite
730 res
= 0x8000000000000000ull
;
733 } else { // x is not a NaN, so it must be infinity
734 if (!x_sign
) { // x is +inf
736 *pfpsf
|= INVALID_EXCEPTION
;
737 // return Integer Indefinite
738 res
= 0x8000000000000000ull
;
739 } else { // x is -inf
741 *pfpsf
|= INVALID_EXCEPTION
;
742 // return Integer Indefinite
743 res
= 0x8000000000000000ull
;
748 // check for non-canonical values (after the check for special values)
749 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
750 || (C1
.w
[1] == 0x0001ed09bead87c0ull
751 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
752 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
753 res
= 0x0000000000000000ull
;
755 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
757 res
= 0x0000000000000000ull
;
759 } else { // x is not special and is not zero
761 // q = nr. of decimal digits in x
762 // determine first the nr. of bits in x
764 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
765 // split the 64-bit value in two 32-bit halves to avoid rounding errors
766 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
767 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
769 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
771 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
773 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
775 } else { // if x < 2^53
776 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
778 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
780 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
781 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
783 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
785 q
= nr_digits
[x_nr_bits
- 1].digits
;
787 q
= nr_digits
[x_nr_bits
- 1].digits1
;
788 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
789 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
790 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
793 exp
= (x_exp
>> 49) - 6176;
795 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
797 *pfpsf
|= INVALID_EXCEPTION
;
798 // return Integer Indefinite
799 res
= 0x8000000000000000ull
;
801 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
802 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
803 // so x rounded to an integer may or may not fit in a signed 64-bit int
804 // the cases that do not fit are identified here; the ones that fit
805 // fall through and will be handled with other cases further,
806 // under '1 <= q + exp <= 19'
807 if (x_sign
) { // if n < 0 and q + exp = 19
808 // if n < -2^63 then n is too large
809 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
810 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 10*2^63, 1<=q<=34
811 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=34
812 C
.w
[1] = 0x0000000000000005ull
;
813 C
.w
[0] = 0x0000000000000000ull
;
814 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
815 // 10^(20-q) is 64-bit, and so is C1
816 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
817 } else if (q
== 20) {
819 } else { // if 21 <= q <= 34
820 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
822 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
824 *pfpsf
|= INVALID_EXCEPTION
;
825 // return Integer Indefinite
826 res
= 0x8000000000000000ull
;
829 // else cases that can be rounded to a 64-bit int fall through
830 // to '1 <= q + exp <= 19'
831 } else { // if n > 0 and q + exp = 19
832 // if n >= 2^63 then n is too large
833 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
834 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34
835 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34
836 C
.w
[1] = 0x0000000000000005ull
;
837 C
.w
[0] = 0x0000000000000000ull
;
838 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
839 // 10^(20-q) is 64-bit, and so is C1
840 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
841 } else if (q
== 20) {
843 } else { // if 21 <= q <= 34
844 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
846 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
848 *pfpsf
|= INVALID_EXCEPTION
;
849 // return Integer Indefinite
850 res
= 0x8000000000000000ull
;
853 // else cases that can be rounded to a 64-bit int fall through
854 // to '1 <= q + exp <= 19'
857 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
858 // Note: some of the cases tested for above fall through to this point
859 // Restore C1 which may have been modified above
860 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
862 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
865 res
= 0xffffffffffffffffull
;
867 res
= 0x0000000000000000ull
;
869 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
870 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
871 // toward zero to a 64-bit signed integer
872 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
873 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
874 // chop off ind digits from the lower part of C1
875 // C1 fits in 127 bits
876 // calculate C* and f*
877 // C* is actually floor(C*) in this case
878 // C* and f* need shifting and masking, as shown by
879 // shiftright128[] and maskhigh128[]
881 // kx = 10^(-x) = ten2mk128[ind - 1]
883 // the approximation of 10^(-x) was rounded up to 118 bits
884 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
885 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
886 Cstar
.w
[1] = P256
.w
[3];
887 Cstar
.w
[0] = P256
.w
[2];
889 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
890 fstar
.w
[1] = P256
.w
[1];
891 fstar
.w
[0] = P256
.w
[0];
892 } else { // 22 <= ind - 1 <= 33
894 Cstar
.w
[0] = P256
.w
[3];
895 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
896 fstar
.w
[2] = P256
.w
[2];
897 fstar
.w
[1] = P256
.w
[1];
898 fstar
.w
[0] = P256
.w
[0];
900 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
901 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
902 // C* = floor(C*) (logical right shift; C has p decimal digits,
903 // correct by Property 1)
906 // shift right C* by Ex-128 = shiftright128[ind]
907 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
908 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
910 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
911 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
912 } else { // 22 <= ind - 1 <= 33
913 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
915 // if the result is negative and inexact, need to add 1 to it
917 // determine inexactness of the rounding of C*
918 // if (0 < f* < 10^(-x)) then
919 // the result is exact
920 // else // if (f* > T*) then
921 // the result is inexact
923 if (fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1] ||
924 (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1] &&
925 fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
926 if (x_sign
) { // positive and inexact
928 if (Cstar
.w
[0] == 0x0)
931 } // else the result is exact
932 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
933 if (fstar
.w
[2] || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
934 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
935 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
936 if (x_sign
) { // positive and inexact
938 if (Cstar
.w
[0] == 0x0)
941 } // else the result is exact
942 } else { // if 22 <= ind <= 33
943 if (fstar
.w
[3] || fstar
.w
[2]
944 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
945 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
946 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
947 if (x_sign
) { // positive and inexact
949 if (Cstar
.w
[0] == 0x0)
952 } // else the result is exact
959 } else if (exp
== 0) {
961 // res = +/-C (exact)
966 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
967 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
969 res
= -C1
.w
[0] * ten2k64
[exp
];
971 res
= C1
.w
[0] * ten2k64
[exp
];
979 /*****************************************************************************
980 * BID128_to_int64_xfloor
981 ****************************************************************************/
983 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
,
984 bid128_to_int64_xfloor
, x
)
989 int exp
; // unbiased exponent
990 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
992 unsigned int x_nr_bits
;
995 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
1000 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1001 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1002 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1005 // check for NaN or Infinity
1006 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
1008 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
1009 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
1011 *pfpsf
|= INVALID_EXCEPTION
;
1012 // return Integer Indefinite
1013 res
= 0x8000000000000000ull
;
1014 } else { // x is QNaN
1016 *pfpsf
|= INVALID_EXCEPTION
;
1017 // return Integer Indefinite
1018 res
= 0x8000000000000000ull
;
1021 } else { // x is not a NaN, so it must be infinity
1022 if (!x_sign
) { // x is +inf
1024 *pfpsf
|= INVALID_EXCEPTION
;
1025 // return Integer Indefinite
1026 res
= 0x8000000000000000ull
;
1027 } else { // x is -inf
1029 *pfpsf
|= INVALID_EXCEPTION
;
1030 // return Integer Indefinite
1031 res
= 0x8000000000000000ull
;
1036 // check for non-canonical values (after the check for special values)
1037 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
1038 || (C1
.w
[1] == 0x0001ed09bead87c0ull
1039 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
1040 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
1041 res
= 0x0000000000000000ull
;
1043 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1045 res
= 0x0000000000000000ull
;
1047 } else { // x is not special and is not zero
1049 // q = nr. of decimal digits in x
1050 // determine first the nr. of bits in x
1052 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
1053 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1054 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
1055 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
1057 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1058 } else { // x < 2^32
1059 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1061 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1063 } else { // if x < 2^53
1064 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
1066 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1068 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1069 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
1071 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1073 q
= nr_digits
[x_nr_bits
- 1].digits
;
1075 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1076 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
1077 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
1078 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
1081 exp
= (x_exp
>> 49) - 6176;
1082 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1084 *pfpsf
|= INVALID_EXCEPTION
;
1085 // return Integer Indefinite
1086 res
= 0x8000000000000000ull
;
1088 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1089 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1090 // so x rounded to an integer may or may not fit in a signed 64-bit int
1091 // the cases that do not fit are identified here; the ones that fit
1092 // fall through and will be handled with other cases further,
1093 // under '1 <= q + exp <= 19'
1094 if (x_sign
) { // if n < 0 and q + exp = 19
1095 // if n < -2^63 then n is too large
1096 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
1097 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 10*2^63, 1<=q<=34
1098 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=34
1099 C
.w
[1] = 0x0000000000000005ull
;
1100 C
.w
[0] = 0x0000000000000000ull
;
1101 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1102 // 10^(20-q) is 64-bit, and so is C1
1103 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1104 } else if (q
== 20) {
1106 } else { // if 21 <= q <= 34
1107 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1109 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
1111 *pfpsf
|= INVALID_EXCEPTION
;
1112 // return Integer Indefinite
1113 res
= 0x8000000000000000ull
;
1116 // else cases that can be rounded to a 64-bit int fall through
1117 // to '1 <= q + exp <= 19'
1118 } else { // if n > 0 and q + exp = 19
1119 // if n >= 2^63 then n is too large
1120 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1121 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34
1122 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34
1123 C
.w
[1] = 0x0000000000000005ull
;
1124 C
.w
[0] = 0x0000000000000000ull
;
1125 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1126 // 10^(20-q) is 64-bit, and so is C1
1127 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1128 } else if (q
== 20) {
1130 } else { // if 21 <= q <= 34
1131 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1133 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
1135 *pfpsf
|= INVALID_EXCEPTION
;
1136 // return Integer Indefinite
1137 res
= 0x8000000000000000ull
;
1140 // else cases that can be rounded to a 64-bit int fall through
1141 // to '1 <= q + exp <= 19'
1144 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1145 // Note: some of the cases tested for above fall through to this point
1146 // Restore C1 which may have been modified above
1147 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1149 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1151 *pfpsf
|= INEXACT_EXCEPTION
;
1154 res
= 0xffffffffffffffffull
;
1156 res
= 0x0000000000000000ull
;
1158 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
1159 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
1160 // toward zero to a 64-bit signed integer
1161 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
1162 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
1163 // chop off ind digits from the lower part of C1
1164 // C1 fits in 127 bits
1165 // calculate C* and f*
1166 // C* is actually floor(C*) in this case
1167 // C* and f* need shifting and masking, as shown by
1168 // shiftright128[] and maskhigh128[]
1170 // kx = 10^(-x) = ten2mk128[ind - 1]
1171 // C* = C1 * 10^(-x)
1172 // the approximation of 10^(-x) was rounded up to 118 bits
1173 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
1174 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1175 Cstar
.w
[1] = P256
.w
[3];
1176 Cstar
.w
[0] = P256
.w
[2];
1178 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
1179 fstar
.w
[1] = P256
.w
[1];
1180 fstar
.w
[0] = P256
.w
[0];
1181 } else { // 22 <= ind - 1 <= 33
1183 Cstar
.w
[0] = P256
.w
[3];
1184 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
1185 fstar
.w
[2] = P256
.w
[2];
1186 fstar
.w
[1] = P256
.w
[1];
1187 fstar
.w
[0] = P256
.w
[0];
1189 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1190 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1191 // C* = floor(C*) (logical right shift; C has p decimal digits,
1192 // correct by Property 1)
1193 // n = C* * 10^(e+x)
1195 // shift right C* by Ex-128 = shiftright128[ind]
1196 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
1197 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1199 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
1200 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1201 } else { // 22 <= ind - 1 <= 33
1202 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
1204 // if the result is negative and inexact, need to add 1 to it
1206 // determine inexactness of the rounding of C*
1207 // if (0 < f* < 10^(-x)) then
1208 // the result is exact
1209 // else // if (f* > T*) then
1210 // the result is inexact
1212 if (fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1] ||
1213 (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1] &&
1214 fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1215 if (x_sign
) { // positive and inexact
1217 if (Cstar
.w
[0] == 0x0)
1220 // set the inexact flag
1221 *pfpsf
|= INEXACT_EXCEPTION
;
1222 } // else the result is exact
1223 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
1224 if (fstar
.w
[2] || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1225 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1226 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1227 if (x_sign
) { // positive and inexact
1229 if (Cstar
.w
[0] == 0x0)
1232 // set the inexact flag
1233 *pfpsf
|= INEXACT_EXCEPTION
;
1234 } // else the result is exact
1235 } else { // if 22 <= ind <= 33
1236 if (fstar
.w
[3] || fstar
.w
[2]
1237 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1238 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1239 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1240 if (x_sign
) { // positive and inexact
1242 if (Cstar
.w
[0] == 0x0)
1245 // set the inexact flag
1246 *pfpsf
|= INEXACT_EXCEPTION
;
1247 } // else the result is exact
1254 } else if (exp
== 0) {
1256 // res = +/-C (exact)
1261 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
1262 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
1264 res
= -C1
.w
[0] * ten2k64
[exp
];
1266 res
= C1
.w
[0] * ten2k64
[exp
];
1274 /*****************************************************************************
1275 * BID128_to_int64_ceil
1276 ****************************************************************************/
1278 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_ceil
,
1284 int exp
; // unbiased exponent
1285 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1286 BID_UI64DOUBLE tmp1
;
1287 unsigned int x_nr_bits
;
1290 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
1295 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1296 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1297 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1300 // check for NaN or Infinity
1301 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
1303 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
1304 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
1306 *pfpsf
|= INVALID_EXCEPTION
;
1307 // return Integer Indefinite
1308 res
= 0x8000000000000000ull
;
1309 } else { // x is QNaN
1311 *pfpsf
|= INVALID_EXCEPTION
;
1312 // return Integer Indefinite
1313 res
= 0x8000000000000000ull
;
1316 } else { // x is not a NaN, so it must be infinity
1317 if (!x_sign
) { // x is +inf
1319 *pfpsf
|= INVALID_EXCEPTION
;
1320 // return Integer Indefinite
1321 res
= 0x8000000000000000ull
;
1322 } else { // x is -inf
1324 *pfpsf
|= INVALID_EXCEPTION
;
1325 // return Integer Indefinite
1326 res
= 0x8000000000000000ull
;
1331 // check for non-canonical values (after the check for special values)
1332 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
1333 || (C1
.w
[1] == 0x0001ed09bead87c0ull
1334 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
1335 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
1336 res
= 0x0000000000000000ull
;
1338 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1340 res
= 0x0000000000000000ull
;
1342 } else { // x is not special and is not zero
1344 // q = nr. of decimal digits in x
1345 // determine first the nr. of bits in x
1347 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
1348 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1349 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
1350 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
1352 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1353 } else { // x < 2^32
1354 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1356 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1358 } else { // if x < 2^53
1359 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
1361 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1363 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1364 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
1366 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1368 q
= nr_digits
[x_nr_bits
- 1].digits
;
1370 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1371 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
1372 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
1373 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
1376 exp
= (x_exp
>> 49) - 6176;
1377 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1379 *pfpsf
|= INVALID_EXCEPTION
;
1380 // return Integer Indefinite
1381 res
= 0x8000000000000000ull
;
1383 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1384 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1385 // so x rounded to an integer may or may not fit in a signed 64-bit int
1386 // the cases that do not fit are identified here; the ones that fit
1387 // fall through and will be handled with other cases further,
1388 // under '1 <= q + exp <= 19'
1389 if (x_sign
) { // if n < 0 and q + exp = 19
1390 // if n <= -2^63 - 1 then n is too large
1391 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1392 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+2), 1<=q<=34
1393 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x5000000000000000a, 1<=q<=34
1394 C
.w
[1] = 0x0000000000000005ull
;
1395 C
.w
[0] = 0x000000000000000aull
;
1396 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1397 // 10^(20-q) is 64-bit, and so is C1
1398 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1399 } else if (q
== 20) {
1401 } else { // if 21 <= q <= 34
1402 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1404 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
1406 *pfpsf
|= INVALID_EXCEPTION
;
1407 // return Integer Indefinite
1408 res
= 0x8000000000000000ull
;
1411 // else cases that can be rounded to a 64-bit int fall through
1412 // to '1 <= q + exp <= 19'
1413 } else { // if n > 0 and q + exp = 19
1414 // if n > 2^63 - 1 then n is too large
1415 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1416 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 10*(2^63-1), 1<=q<=34
1417 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=34
1418 C
.w
[1] = 0x0000000000000004ull
;
1419 C
.w
[0] = 0xfffffffffffffff6ull
;
1420 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1421 // 10^(20-q) is 64-bit, and so is C1
1422 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1423 } else if (q
== 20) {
1425 } else { // if 21 <= q <= 34
1426 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1428 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
1430 *pfpsf
|= INVALID_EXCEPTION
;
1431 // return Integer Indefinite
1432 res
= 0x8000000000000000ull
;
1435 // else cases that can be rounded to a 64-bit int fall through
1436 // to '1 <= q + exp <= 19'
1439 // n is not too large to be converted to int64: -2^63-1 < n <= 2^63 - 1
1440 // Note: some of the cases tested for above fall through to this point
1441 // Restore C1 which may have been modified above
1442 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1444 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1447 res
= 0x0000000000000000ull
;
1449 res
= 0x0000000000000001ull
;
1451 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
1452 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1453 // up to a 64-bit signed integer
1454 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
1455 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
1456 // chop off ind digits from the lower part of C1
1457 // C1 fits in 127 bits
1458 // calculate C* and f*
1459 // C* is actually floor(C*) in this case
1460 // C* and f* need shifting and masking, as shown by
1461 // shiftright128[] and maskhigh128[]
1463 // kx = 10^(-x) = ten2mk128[ind - 1]
1464 // C* = C1 * 10^(-x)
1465 // the approximation of 10^(-x) was rounded up to 118 bits
1466 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
1467 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1468 Cstar
.w
[1] = P256
.w
[3];
1469 Cstar
.w
[0] = P256
.w
[2];
1471 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
1472 fstar
.w
[1] = P256
.w
[1];
1473 fstar
.w
[0] = P256
.w
[0];
1474 } else { // 22 <= ind - 1 <= 33
1476 Cstar
.w
[0] = P256
.w
[3];
1477 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
1478 fstar
.w
[2] = P256
.w
[2];
1479 fstar
.w
[1] = P256
.w
[1];
1480 fstar
.w
[0] = P256
.w
[0];
1482 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1483 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1484 // C* = floor(C*) (logical right shift; C has p decimal digits,
1485 // correct by Property 1)
1486 // n = C* * 10^(e+x)
1488 // shift right C* by Ex-128 = shiftright128[ind]
1489 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
1490 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1492 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
1493 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1494 } else { // 22 <= ind - 1 <= 33
1495 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
1497 // if the result is positive and inexact, need to add 1 to it
1499 // determine inexactness of the rounding of C*
1500 // if (0 < f* < 10^(-x)) then
1501 // the result is exact
1502 // else // if (f* > T*) then
1503 // the result is inexact
1505 if (fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1506 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1507 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1508 if (!x_sign
) { // positive and inexact
1510 if (Cstar
.w
[0] == 0x0)
1513 } // else the result is exact
1514 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
1515 if (fstar
.w
[2] || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1516 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1517 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1518 if (!x_sign
) { // positive and inexact
1520 if (Cstar
.w
[0] == 0x0)
1523 } // else the result is exact
1524 } else { // if 22 <= ind <= 33
1525 if (fstar
.w
[3] || fstar
.w
[2]
1526 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1527 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1528 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1529 if (!x_sign
) { // positive and inexact
1531 if (Cstar
.w
[0] == 0x0)
1534 } // else the result is exact
1540 } else if (exp
== 0) {
1542 // res = +/-C (exact)
1547 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
1548 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
1550 res
= -C1
.w
[0] * ten2k64
[exp
];
1552 res
= C1
.w
[0] * ten2k64
[exp
];
1560 /*****************************************************************************
1561 * BID128_to_int64_xceil
1562 ****************************************************************************/
1564 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_xceil
,
1570 int exp
; // unbiased exponent
1571 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1572 BID_UI64DOUBLE tmp1
;
1573 unsigned int x_nr_bits
;
1576 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
1581 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1582 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1583 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1586 // check for NaN or Infinity
1587 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
1589 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
1590 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
1592 *pfpsf
|= INVALID_EXCEPTION
;
1593 // return Integer Indefinite
1594 res
= 0x8000000000000000ull
;
1595 } else { // x is QNaN
1597 *pfpsf
|= INVALID_EXCEPTION
;
1598 // return Integer Indefinite
1599 res
= 0x8000000000000000ull
;
1602 } else { // x is not a NaN, so it must be infinity
1603 if (!x_sign
) { // x is +inf
1605 *pfpsf
|= INVALID_EXCEPTION
;
1606 // return Integer Indefinite
1607 res
= 0x8000000000000000ull
;
1608 } else { // x is -inf
1610 *pfpsf
|= INVALID_EXCEPTION
;
1611 // return Integer Indefinite
1612 res
= 0x8000000000000000ull
;
1617 // check for non-canonical values (after the check for special values)
1618 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
1619 || (C1
.w
[1] == 0x0001ed09bead87c0ull
1620 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
1621 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
1622 res
= 0x0000000000000000ull
;
1624 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1626 res
= 0x0000000000000000ull
;
1628 } else { // x is not special and is not zero
1630 // q = nr. of decimal digits in x
1631 // determine first the nr. of bits in x
1633 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
1634 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1635 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
1636 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
1638 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1639 } else { // x < 2^32
1640 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1642 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1644 } else { // if x < 2^53
1645 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
1647 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1649 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1650 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
1652 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1654 q
= nr_digits
[x_nr_bits
- 1].digits
;
1656 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1657 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
1658 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
1659 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
1662 exp
= (x_exp
>> 49) - 6176;
1663 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1665 *pfpsf
|= INVALID_EXCEPTION
;
1666 // return Integer Indefinite
1667 res
= 0x8000000000000000ull
;
1669 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1670 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1671 // so x rounded to an integer may or may not fit in a signed 64-bit int
1672 // the cases that do not fit are identified here; the ones that fit
1673 // fall through and will be handled with other cases further,
1674 // under '1 <= q + exp <= 19'
1675 if (x_sign
) { // if n < 0 and q + exp = 19
1676 // if n <= -2^63 - 1 then n is too large
1677 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1678 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+2), 1<=q<=34
1679 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x5000000000000000a, 1<=q<=34
1680 C
.w
[1] = 0x0000000000000005ull
;
1681 C
.w
[0] = 0x000000000000000aull
;
1682 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1683 // 10^(20-q) is 64-bit, and so is C1
1684 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1685 } else if (q
== 20) {
1687 } else { // if 21 <= q <= 34
1688 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1690 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
1692 *pfpsf
|= INVALID_EXCEPTION
;
1693 // return Integer Indefinite
1694 res
= 0x8000000000000000ull
;
1697 // else cases that can be rounded to a 64-bit int fall through
1698 // to '1 <= q + exp <= 19'
1699 } else { // if n > 0 and q + exp = 19
1700 // if n > 2^63 - 1 then n is too large
1701 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1702 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 10*(2^63-1), 1<=q<=34
1703 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=34
1704 C
.w
[1] = 0x0000000000000004ull
;
1705 C
.w
[0] = 0xfffffffffffffff6ull
;
1706 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1707 // 10^(20-q) is 64-bit, and so is C1
1708 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1709 } else if (q
== 20) {
1711 } else { // if 21 <= q <= 34
1712 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1714 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] > C
.w
[0])) {
1716 *pfpsf
|= INVALID_EXCEPTION
;
1717 // return Integer Indefinite
1718 res
= 0x8000000000000000ull
;
1721 // else cases that can be rounded to a 64-bit int fall through
1722 // to '1 <= q + exp <= 19'
1725 // n is not too large to be converted to int64: -2^63-1 < n <= 2^63 - 1
1726 // Note: some of the cases tested for above fall through to this point
1727 // Restore C1 which may have been modified above
1728 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1730 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1732 *pfpsf
|= INEXACT_EXCEPTION
;
1735 res
= 0x0000000000000000ull
;
1737 res
= 0x0000000000000001ull
;
1739 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
1740 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1741 // up to a 64-bit signed integer
1742 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
1743 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
1744 // chop off ind digits from the lower part of C1
1745 // C1 fits in 127 bits
1746 // calculate C* and f*
1747 // C* is actually floor(C*) in this case
1748 // C* and f* need shifting and masking, as shown by
1749 // shiftright128[] and maskhigh128[]
1751 // kx = 10^(-x) = ten2mk128[ind - 1]
1752 // C* = C1 * 10^(-x)
1753 // the approximation of 10^(-x) was rounded up to 118 bits
1754 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
1755 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1756 Cstar
.w
[1] = P256
.w
[3];
1757 Cstar
.w
[0] = P256
.w
[2];
1759 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
1760 fstar
.w
[1] = P256
.w
[1];
1761 fstar
.w
[0] = P256
.w
[0];
1762 } else { // 22 <= ind - 1 <= 33
1764 Cstar
.w
[0] = P256
.w
[3];
1765 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
1766 fstar
.w
[2] = P256
.w
[2];
1767 fstar
.w
[1] = P256
.w
[1];
1768 fstar
.w
[0] = P256
.w
[0];
1770 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
1771 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1772 // C* = floor(C*) (logical right shift; C has p decimal digits,
1773 // correct by Property 1)
1774 // n = C* * 10^(e+x)
1776 // shift right C* by Ex-128 = shiftright128[ind]
1777 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
1778 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
1780 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
1781 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
1782 } else { // 22 <= ind - 1 <= 33
1783 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
1785 // if the result is positive and inexact, need to add 1 to it
1787 // determine inexactness of the rounding of C*
1788 // if (0 < f* < 10^(-x)) then
1789 // the result is exact
1790 // else // if (f* > T*) then
1791 // the result is inexact
1793 if (fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1794 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1795 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1796 if (!x_sign
) { // positive and inexact
1798 if (Cstar
.w
[0] == 0x0)
1801 // set the inexact flag
1802 *pfpsf
|= INEXACT_EXCEPTION
;
1803 } // else the result is exact
1804 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
1805 if (fstar
.w
[2] || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1806 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1807 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1808 if (!x_sign
) { // positive and inexact
1810 if (Cstar
.w
[0] == 0x0)
1813 // set the inexact flag
1814 *pfpsf
|= INEXACT_EXCEPTION
;
1815 } // else the result is exact
1816 } else { // if 22 <= ind <= 33
1817 if (fstar
.w
[3] || fstar
.w
[2]
1818 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
1819 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
1820 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
1821 if (!x_sign
) { // positive and inexact
1823 if (Cstar
.w
[0] == 0x0)
1826 // set the inexact flag
1827 *pfpsf
|= INEXACT_EXCEPTION
;
1828 } // else the result is exact
1835 } else if (exp
== 0) {
1837 // res = +/-C (exact)
1842 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
1843 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
1845 res
= -C1
.w
[0] * ten2k64
[exp
];
1847 res
= C1
.w
[0] * ten2k64
[exp
];
1855 /*****************************************************************************
1856 * BID128_to_int64_int
1857 ****************************************************************************/
1859 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_int
,
1865 int exp
; // unbiased exponent
1866 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1867 BID_UI64DOUBLE tmp1
;
1868 unsigned int x_nr_bits
;
1871 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
1875 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1876 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1877 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
1880 // check for NaN or Infinity
1881 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
1883 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
1884 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
1886 *pfpsf
|= INVALID_EXCEPTION
;
1887 // return Integer Indefinite
1888 res
= 0x8000000000000000ull
;
1889 } else { // x is QNaN
1891 *pfpsf
|= INVALID_EXCEPTION
;
1892 // return Integer Indefinite
1893 res
= 0x8000000000000000ull
;
1896 } else { // x is not a NaN, so it must be infinity
1897 if (!x_sign
) { // x is +inf
1899 *pfpsf
|= INVALID_EXCEPTION
;
1900 // return Integer Indefinite
1901 res
= 0x8000000000000000ull
;
1902 } else { // x is -inf
1904 *pfpsf
|= INVALID_EXCEPTION
;
1905 // return Integer Indefinite
1906 res
= 0x8000000000000000ull
;
1911 // check for non-canonical values (after the check for special values)
1912 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
1913 || (C1
.w
[1] == 0x0001ed09bead87c0ull
1914 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
1915 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
1916 res
= 0x0000000000000000ull
;
1918 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
1920 res
= 0x0000000000000000ull
;
1922 } else { // x is not special and is not zero
1924 // q = nr. of decimal digits in x
1925 // determine first the nr. of bits in x
1927 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
1928 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1929 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
1930 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
1932 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1933 } else { // x < 2^32
1934 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
1936 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1938 } else { // if x < 2^53
1939 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
1941 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1943 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
1944 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
1946 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1948 q
= nr_digits
[x_nr_bits
- 1].digits
;
1950 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1951 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
1952 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
1953 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
1956 exp
= (x_exp
>> 49) - 6176;
1957 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1959 *pfpsf
|= INVALID_EXCEPTION
;
1960 // return Integer Indefinite
1961 res
= 0x8000000000000000ull
;
1963 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1964 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1965 // so x rounded to an integer may or may not fit in a signed 64-bit int
1966 // the cases that do not fit are identified here; the ones that fit
1967 // fall through and will be handled with other cases further,
1968 // under '1 <= q + exp <= 19'
1969 if (x_sign
) { // if n < 0 and q + exp = 19
1970 // if n <= -2^63 - 1 then n is too large
1971 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1972 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=34
1973 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=34
1974 C
.w
[1] = 0x0000000000000005ull
;
1975 C
.w
[0] = 0x000000000000000aull
;
1976 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
1977 // 10^(20-q) is 64-bit, and so is C1
1978 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
1979 } else if (q
== 20) {
1981 } else { // if 21 <= q <= 34
1982 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
1984 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
1986 *pfpsf
|= INVALID_EXCEPTION
;
1987 // return Integer Indefinite
1988 res
= 0x8000000000000000ull
;
1991 // else cases that can be rounded to a 64-bit int fall through
1992 // to '1 <= q + exp <= 19'
1993 } else { // if n > 0 and q + exp = 19
1994 // if n >= 2^63 then n is too large
1995 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1996 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34
1997 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34
1998 C
.w
[1] = 0x0000000000000005ull
;
1999 C
.w
[0] = 0x0000000000000000ull
;
2000 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2001 // 10^(20-q) is 64-bit, and so is C1
2002 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2003 } else if (q
== 20) {
2005 } else { // if 21 <= q <= 34
2006 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2008 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2010 *pfpsf
|= INVALID_EXCEPTION
;
2011 // return Integer Indefinite
2012 res
= 0x8000000000000000ull
;
2015 // else cases that can be rounded to a 64-bit int fall through
2016 // to '1 <= q + exp <= 19'
2019 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
2020 // Note: some of the cases tested for above fall through to this point
2021 // Restore C1 which may have been modified above
2022 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2024 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2026 res
= 0x0000000000000000ull
;
2028 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
2029 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
2030 // toward zero to a 64-bit signed integer
2031 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
2032 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
2033 // chop off ind digits from the lower part of C1
2034 // C1 fits in 127 bits
2035 // calculate C* and f*
2036 // C* is actually floor(C*) in this case
2037 // C* and f* need shifting and masking, as shown by
2038 // shiftright128[] and maskhigh128[]
2040 // kx = 10^(-x) = ten2mk128[ind - 1]
2041 // C* = C1 * 10^(-x)
2042 // the approximation of 10^(-x) was rounded up to 118 bits
2043 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
2044 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2045 Cstar
.w
[1] = P256
.w
[3];
2046 Cstar
.w
[0] = P256
.w
[2];
2047 } else { // 22 <= ind - 1 <= 33
2049 Cstar
.w
[0] = P256
.w
[3];
2051 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2052 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2053 // C* = floor(C*) (logical right shift; C has p decimal digits,
2054 // correct by Property 1)
2055 // n = C* * 10^(e+x)
2057 // shift right C* by Ex-128 = shiftright128[ind]
2058 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
2059 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2061 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
2062 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2063 } else { // 22 <= ind - 1 <= 33
2064 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
2070 } else if (exp
== 0) {
2072 // res = +/-C (exact)
2077 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
2078 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
2080 res
= -C1
.w
[0] * ten2k64
[exp
];
2082 res
= C1
.w
[0] * ten2k64
[exp
];
2090 /*****************************************************************************
2091 * BID128_to_xint64_xint
2092 ****************************************************************************/
2094 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
, bid128_to_int64_xint
,
2100 int exp
; // unbiased exponent
2101 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2102 BID_UI64DOUBLE tmp1
;
2103 unsigned int x_nr_bits
;
2106 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
2111 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
2112 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
2113 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2116 // check for NaN or Infinity
2117 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
2119 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
2120 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
2122 *pfpsf
|= INVALID_EXCEPTION
;
2123 // return Integer Indefinite
2124 res
= 0x8000000000000000ull
;
2125 } else { // x is QNaN
2127 *pfpsf
|= INVALID_EXCEPTION
;
2128 // return Integer Indefinite
2129 res
= 0x8000000000000000ull
;
2132 } else { // x is not a NaN, so it must be infinity
2133 if (!x_sign
) { // x is +inf
2135 *pfpsf
|= INVALID_EXCEPTION
;
2136 // return Integer Indefinite
2137 res
= 0x8000000000000000ull
;
2138 } else { // x is -inf
2140 *pfpsf
|= INVALID_EXCEPTION
;
2141 // return Integer Indefinite
2142 res
= 0x8000000000000000ull
;
2147 // check for non-canonical values (after the check for special values)
2148 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
2149 || (C1
.w
[1] == 0x0001ed09bead87c0ull
2150 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
2151 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
2152 res
= 0x0000000000000000ull
;
2154 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
2156 res
= 0x0000000000000000ull
;
2158 } else { // x is not special and is not zero
2160 // q = nr. of decimal digits in x
2161 // determine first the nr. of bits in x
2163 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
2164 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2165 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
2166 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
2168 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2169 } else { // x < 2^32
2170 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
2172 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2174 } else { // if x < 2^53
2175 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
2177 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2179 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2180 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
2182 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2184 q
= nr_digits
[x_nr_bits
- 1].digits
;
2186 q
= nr_digits
[x_nr_bits
- 1].digits1
;
2187 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
2188 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
2189 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
2192 exp
= (x_exp
>> 49) - 6176;
2193 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2195 *pfpsf
|= INVALID_EXCEPTION
;
2196 // return Integer Indefinite
2197 res
= 0x8000000000000000ull
;
2199 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
2200 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2201 // so x rounded to an integer may or may not fit in a signed 64-bit int
2202 // the cases that do not fit are identified here; the ones that fit
2203 // fall through and will be handled with other cases further,
2204 // under '1 <= q + exp <= 19'
2205 if (x_sign
) { // if n < 0 and q + exp = 19
2206 // if n <= -2^63 - 1 then n is too large
2207 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
2208 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=34
2209 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=34
2210 C
.w
[1] = 0x0000000000000005ull
;
2211 C
.w
[0] = 0x000000000000000aull
;
2212 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2213 // 10^(20-q) is 64-bit, and so is C1
2214 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2215 } else if (q
== 20) {
2217 } else { // if 21 <= q <= 34
2218 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2220 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2222 *pfpsf
|= INVALID_EXCEPTION
;
2223 // return Integer Indefinite
2224 res
= 0x8000000000000000ull
;
2227 // else cases that can be rounded to a 64-bit int fall through
2228 // to '1 <= q + exp <= 19'
2229 } else { // if n > 0 and q + exp = 19
2230 // if n >= 2^63 then n is too large
2231 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
2232 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34
2233 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34
2234 C
.w
[1] = 0x0000000000000005ull
;
2235 C
.w
[0] = 0x0000000000000000ull
;
2236 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2237 // 10^(20-q) is 64-bit, and so is C1
2238 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2239 } else if (q
== 20) {
2241 } else { // if 21 <= q <= 34
2242 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2244 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2246 *pfpsf
|= INVALID_EXCEPTION
;
2247 // return Integer Indefinite
2248 res
= 0x8000000000000000ull
;
2251 // else cases that can be rounded to a 64-bit int fall through
2252 // to '1 <= q + exp <= 19'
2255 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
2256 // Note: some of the cases tested for above fall through to this point
2257 // Restore C1 which may have been modified above
2258 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2260 if ((q
+ exp
) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2262 *pfpsf
|= INEXACT_EXCEPTION
;
2264 res
= 0x0000000000000000ull
;
2266 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
2267 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
2268 // toward zero to a 64-bit signed integer
2269 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
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];
2286 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
2287 fstar
.w
[1] = P256
.w
[1];
2288 fstar
.w
[0] = P256
.w
[0];
2289 } else { // 22 <= ind - 1 <= 33
2291 Cstar
.w
[0] = P256
.w
[3];
2292 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
2293 fstar
.w
[2] = P256
.w
[2];
2294 fstar
.w
[1] = P256
.w
[1];
2295 fstar
.w
[0] = P256
.w
[0];
2297 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2298 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2299 // C* = floor(C*) (logical right shift; C has p decimal digits,
2300 // correct by Property 1)
2301 // n = C* * 10^(e+x)
2303 // shift right C* by Ex-128 = shiftright128[ind]
2304 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
2305 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2307 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
2308 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2309 } else { // 22 <= ind - 1 <= 33
2310 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
2312 // determine inexactness of the rounding of C*
2313 // if (0 < f* < 10^(-x)) then
2314 // the result is exact
2315 // else // if (f* > T*) then
2316 // the result is inexact
2318 if (fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
2319 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
2320 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
2321 // set the inexact flag
2322 *pfpsf
|= INEXACT_EXCEPTION
;
2323 } // else the result is exact
2324 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
2325 if (fstar
.w
[2] || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
2326 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
2327 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
2328 // set the inexact flag
2329 *pfpsf
|= INEXACT_EXCEPTION
;
2331 } else { // if 22 <= ind <= 33
2332 if (fstar
.w
[3] || fstar
.w
[2]
2333 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
2334 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
2335 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
2336 // set the inexact flag
2337 *pfpsf
|= INEXACT_EXCEPTION
;
2345 } else if (exp
== 0) {
2347 // res = +/-C (exact)
2352 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
2353 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
2355 res
= -C1
.w
[0] * ten2k64
[exp
];
2357 res
= C1
.w
[0] * ten2k64
[exp
];
2365 /*****************************************************************************
2366 * BID128_to_int64_rninta
2367 ****************************************************************************/
2369 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
,
2370 bid128_to_int64_rninta
, x
)
2375 int exp
; // unbiased exponent
2376 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2378 BID_UI64DOUBLE tmp1
;
2379 unsigned int x_nr_bits
;
2382 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
2386 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
2387 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
2388 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2391 // check for NaN or Infinity
2392 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
2394 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
2395 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
2397 *pfpsf
|= INVALID_EXCEPTION
;
2398 // return Integer Indefinite
2399 res
= 0x8000000000000000ull
;
2400 } else { // x is QNaN
2402 *pfpsf
|= INVALID_EXCEPTION
;
2403 // return Integer Indefinite
2404 res
= 0x8000000000000000ull
;
2407 } else { // x is not a NaN, so it must be infinity
2408 if (!x_sign
) { // x is +inf
2410 *pfpsf
|= INVALID_EXCEPTION
;
2411 // return Integer Indefinite
2412 res
= 0x8000000000000000ull
;
2413 } else { // x is -inf
2415 *pfpsf
|= INVALID_EXCEPTION
;
2416 // return Integer Indefinite
2417 res
= 0x8000000000000000ull
;
2422 // check for non-canonical values (after the check for special values)
2423 if ((C1
.w
[1] > 0x0001ed09bead87c0ull
)
2424 || (C1
.w
[1] == 0x0001ed09bead87c0ull
2425 && (C1
.w
[0] > 0x378d8e63ffffffffull
))
2426 || ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
2427 res
= 0x0000000000000000ull
;
2429 } else if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
2431 res
= 0x0000000000000000ull
;
2433 } else { // x is not special and is not zero
2435 // q = nr. of decimal digits in x
2436 // determine first the nr. of bits in x
2438 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
2439 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2440 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
2441 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
2443 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2444 } else { // x < 2^32
2445 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
2447 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2449 } else { // if x < 2^53
2450 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
2452 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2454 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2455 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
2457 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2459 q
= nr_digits
[x_nr_bits
- 1].digits
;
2461 q
= nr_digits
[x_nr_bits
- 1].digits1
;
2462 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
2463 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
2464 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
2467 exp
= (x_exp
>> 49) - 6176;
2468 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2470 *pfpsf
|= INVALID_EXCEPTION
;
2471 // return Integer Indefinite
2472 res
= 0x8000000000000000ull
;
2474 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
2475 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2476 // so x rounded to an integer may or may not fit in a signed 64-bit int
2477 // the cases that do not fit are identified here; the ones that fit
2478 // fall through and will be handled with other cases further,
2479 // under '1 <= q + exp <= 19'
2480 if (x_sign
) { // if n < 0 and q + exp = 19
2481 // if n <= -2^63 - 1/2 then n is too large
2482 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
2483 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=34
2484 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=34
2485 C
.w
[1] = 0x0000000000000005ull
;
2486 C
.w
[0] = 0000000000000005ull;
2487 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2488 // 10^(20-q) is 64-bit, and so is C1
2489 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2490 } else if (q
== 20) {
2492 } else { // if 21 <= q <= 34
2493 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2495 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2497 *pfpsf
|= INVALID_EXCEPTION
;
2498 // return Integer Indefinite
2499 res
= 0x8000000000000000ull
;
2502 // else cases that can be rounded to a 64-bit int fall through
2503 // to '1 <= q + exp <= 19'
2504 } else { // if n > 0 and q + exp = 19
2505 // if n >= 2^63 - 1/2 then n is too large
2506 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
2507 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34
2508 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34
2509 C
.w
[1] = 0x0000000000000004ull
;
2510 C
.w
[0] = 0xfffffffffffffffbull
;
2511 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2512 // 10^(20-q) is 64-bit, and so is C1
2513 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2514 } else if (q
== 20) {
2516 } else { // if 21 <= q <= 34
2517 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2519 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2521 *pfpsf
|= INVALID_EXCEPTION
;
2522 // return Integer Indefinite
2523 res
= 0x8000000000000000ull
;
2526 // else cases that can be rounded to a 64-bit int fall through
2527 // to '1 <= q + exp <= 19'
2530 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
2531 // Note: some of the cases tested for above fall through to this point
2532 // Restore C1 which may have been modified above
2533 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2535 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2537 res
= 0x0000000000000000ull
;
2539 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2540 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
2545 if (ind
<= 18) { // 0 <= ind <= 18
2546 if ((C1
.w
[1] == 0) && (C1
.w
[0] < midpoint64
[ind
])) {
2547 res
= 0x0000000000000000ull
; // return 0
2548 } else if (x_sign
) { // n < 0
2549 res
= 0xffffffffffffffffull
; // return -1
2551 res
= 0x0000000000000001ull
; // return +1
2553 } else { // 19 <= ind <= 33
2554 if ((C1
.w
[1] < midpoint128
[ind
- 19].w
[1])
2555 || ((C1
.w
[1] == midpoint128
[ind
- 19].w
[1])
2556 && (C1
.w
[0] < midpoint128
[ind
- 19].w
[0]))) {
2557 res
= 0x0000000000000000ull
; // return 0
2558 } else if (x_sign
) { // n < 0
2559 res
= 0xffffffffffffffffull
; // return -1
2561 res
= 0x0000000000000001ull
; // return +1
2564 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
2565 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2566 // to nearest to a 64-bit signed integer
2567 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
2568 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
2569 // chop off ind digits from the lower part of C1
2570 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
2573 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
2575 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
2576 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].w
[1];
2578 if (C1
.w
[0] < tmp64
)
2580 // calculate C* and f*
2581 // C* is actually floor(C*) in this case
2582 // C* and f* need shifting and masking, as shown by
2583 // shiftright128[] and maskhigh128[]
2585 // kx = 10^(-x) = ten2mk128[ind - 1]
2586 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2587 // the approximation of 10^(-x) was rounded up to 118 bits
2588 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
2589 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2590 Cstar
.w
[1] = P256
.w
[3];
2591 Cstar
.w
[0] = P256
.w
[2];
2592 } else { // 22 <= ind - 1 <= 33
2594 Cstar
.w
[0] = P256
.w
[3];
2596 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2597 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2598 // if (0 < f* < 10^(-x)) then the result is a midpoint
2599 // if floor(C*) is even then C* = floor(C*) - logical right
2600 // shift; C* has p decimal digits, correct by Prop. 1)
2601 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2602 // shift; C* has p decimal digits, correct by Pr. 1)
2604 // C* = floor(C*) (logical right shift; C has p decimal digits,
2605 // correct by Property 1)
2606 // n = C* * 10^(e+x)
2608 // shift right C* by Ex-128 = shiftright128[ind]
2609 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
2610 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2612 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
2613 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2614 } else { // 22 <= ind - 1 <= 33
2615 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
2618 // if the result was a midpoint it was rounded away from zero
2623 } else if (exp
== 0) {
2625 // res = +/-C (exact)
2630 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
2631 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
2633 res
= -C1
.w
[0] * ten2k64
[exp
];
2635 res
= C1
.w
[0] * ten2k64
[exp
];
2643 /*****************************************************************************
2644 * BID128_to_int64_xrninta
2645 ****************************************************************************/
2647 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64
,
2648 bid128_to_int64_xrninta
, x
)
2653 int exp
; // unbiased exponent
2654 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2655 UINT64 tmp64
, tmp64A
;
2656 BID_UI64DOUBLE tmp1
;
2657 unsigned int x_nr_bits
;
2660 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
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2749 *pfpsf
|= INVALID_EXCEPTION
;
2750 // return Integer Indefinite
2751 res
= 0x8000000000000000ull
;
2753 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...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 a signed 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 <= 19'
2759 if (x_sign
) { // if n < 0 and q + exp = 19
2760 // if n <= -2^63 - 1/2 then n is too large
2761 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
2762 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=34
2763 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=34
2764 C
.w
[1] = 0x0000000000000005ull
;
2765 C
.w
[0] = 0000000000000005ull;
2766 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2767 // 10^(20-q) is 64-bit, and so is C1
2768 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2769 } else if (q
== 20) {
2771 } else { // if 21 <= q <= 34
2772 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2774 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2776 *pfpsf
|= INVALID_EXCEPTION
;
2777 // return Integer Indefinite
2778 res
= 0x8000000000000000ull
;
2781 // else cases that can be rounded to a 64-bit int fall through
2782 // to '1 <= q + exp <= 19'
2783 } else { // if n > 0 and q + exp = 19
2784 // if n >= 2^63 - 1/2 then n is too large
2785 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
2786 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34
2787 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34
2788 C
.w
[1] = 0x0000000000000004ull
;
2789 C
.w
[0] = 0xfffffffffffffffbull
;
2790 if (q
<= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 =>
2791 // 10^(20-q) is 64-bit, and so is C1
2792 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[20 - q
]);
2793 } else if (q
== 20) {
2795 } else { // if 21 <= q <= 34
2796 __mul_128x64_to_128 (C
, ten2k64
[q
- 20], C
); // max 47-bit x 67-bit
2798 if (C1
.w
[1] > C
.w
[1] || (C1
.w
[1] == C
.w
[1] && C1
.w
[0] >= C
.w
[0])) {
2800 *pfpsf
|= INVALID_EXCEPTION
;
2801 // return Integer Indefinite
2802 res
= 0x8000000000000000ull
;
2805 // else cases that can be rounded to a 64-bit int fall through
2806 // to '1 <= q + exp <= 19'
2809 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
2810 // Note: some of the cases tested for above fall through to this point
2811 // Restore C1 which may have been modified above
2812 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
2814 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2816 *pfpsf
|= INEXACT_EXCEPTION
;
2818 res
= 0x0000000000000000ull
;
2820 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2821 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
2826 if (ind
<= 18) { // 0 <= ind <= 18
2827 if ((C1
.w
[1] == 0) && (C1
.w
[0] < midpoint64
[ind
])) {
2828 res
= 0x0000000000000000ull
; // return 0
2829 } else if (x_sign
) { // n < 0
2830 res
= 0xffffffffffffffffull
; // return -1
2832 res
= 0x0000000000000001ull
; // return +1
2834 } else { // 19 <= ind <= 33
2835 if ((C1
.w
[1] < midpoint128
[ind
- 19].w
[1])
2836 || ((C1
.w
[1] == midpoint128
[ind
- 19].w
[1])
2837 && (C1
.w
[0] < midpoint128
[ind
- 19].w
[0]))) {
2838 res
= 0x0000000000000000ull
; // return 0
2839 } else if (x_sign
) { // n < 0
2840 res
= 0xffffffffffffffffull
; // return -1
2842 res
= 0x0000000000000001ull
; // return +1
2846 *pfpsf
|= INEXACT_EXCEPTION
;
2847 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18)
2848 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2849 // to nearest to a 64-bit signed integer
2850 if (exp
< 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19
2851 ind
= -exp
; // 1 <= ind <= 33; ind is a synonym for 'x'
2852 // chop off ind digits from the lower part of C1
2853 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
2856 C1
.w
[0] = C1
.w
[0] + midpoint64
[ind
- 1];
2858 C1
.w
[0] = C1
.w
[0] + midpoint128
[ind
- 20].w
[0];
2859 C1
.w
[1] = C1
.w
[1] + midpoint128
[ind
- 20].w
[1];
2861 if (C1
.w
[0] < tmp64
)
2863 // calculate C* and f*
2864 // C* is actually floor(C*) in this case
2865 // C* and f* need shifting and masking, as shown by
2866 // shiftright128[] and maskhigh128[]
2868 // kx = 10^(-x) = ten2mk128[ind - 1]
2869 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2870 // the approximation of 10^(-x) was rounded up to 118 bits
2871 __mul_128x128_to_256 (P256
, C1
, ten2mk128
[ind
- 1]);
2872 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2873 Cstar
.w
[1] = P256
.w
[3];
2874 Cstar
.w
[0] = P256
.w
[2];
2876 fstar
.w
[2] = P256
.w
[2] & maskhigh128
[ind
- 1];
2877 fstar
.w
[1] = P256
.w
[1];
2878 fstar
.w
[0] = P256
.w
[0];
2879 } else { // 22 <= ind - 1 <= 33
2881 Cstar
.w
[0] = P256
.w
[3];
2882 fstar
.w
[3] = P256
.w
[3] & maskhigh128
[ind
- 1];
2883 fstar
.w
[2] = P256
.w
[2];
2884 fstar
.w
[1] = P256
.w
[1];
2885 fstar
.w
[0] = P256
.w
[0];
2887 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
2888 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2889 // if (0 < f* < 10^(-x)) then the result is a midpoint
2890 // if floor(C*) is even then C* = floor(C*) - logical right
2891 // shift; C* has p decimal digits, correct by Prop. 1)
2892 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2893 // shift; C* has p decimal digits, correct by Pr. 1)
2895 // C* = floor(C*) (logical right shift; C has p decimal digits,
2896 // correct by Property 1)
2897 // n = C* * 10^(e+x)
2899 // shift right C* by Ex-128 = shiftright128[ind]
2900 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 102
2901 if (ind
- 1 <= 21) { // 0 <= ind - 1 <= 21
2903 (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
2904 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
2905 } else { // 22 <= ind - 1 <= 33
2906 Cstar
.w
[0] = (Cstar
.w
[0] >> (shift
- 64)); // 2 <= shift - 64 <= 38
2908 // determine inexactness of the rounding of C*
2909 // if (0 < f* - 1/2 < 10^(-x)) then
2910 // the result is exact
2911 // else // if (f* - 1/2 > T*) then
2912 // the result is inexact
2914 if (fstar
.w
[1] > 0x8000000000000000ull
||
2915 (fstar
.w
[1] == 0x8000000000000000ull
2916 && fstar
.w
[0] > 0x0ull
)) {
2917 // f* > 1/2 and the result may be exact
2918 tmp64
= fstar
.w
[1] - 0x8000000000000000ull
; // f* - 1/2
2919 if (tmp64
> ten2mk128trunc
[ind
- 1].w
[1]
2920 || (tmp64
== ten2mk128trunc
[ind
- 1].w
[1]
2921 && fstar
.w
[0] >= ten2mk128trunc
[ind
- 1].w
[0])) {
2922 // set the inexact flag
2923 *pfpsf
|= INEXACT_EXCEPTION
;
2924 } // else the result is exact
2925 } else { // the result is inexact; f2* <= 1/2
2926 // set the inexact flag
2927 *pfpsf
|= INEXACT_EXCEPTION
;
2929 } else if (ind
- 1 <= 21) { // if 3 <= ind <= 21
2930 if (fstar
.w
[3] > 0x0 ||
2931 (fstar
.w
[3] == 0x0 && fstar
.w
[2] > onehalf128
[ind
- 1]) ||
2932 (fstar
.w
[3] == 0x0 && fstar
.w
[2] == onehalf128
[ind
- 1] &&
2933 (fstar
.w
[1] || fstar
.w
[0]))) {
2934 // f2* > 1/2 and the result may be exact
2935 // Calculate f2* - 1/2
2936 tmp64
= fstar
.w
[2] - onehalf128
[ind
- 1];
2937 tmp64A
= fstar
.w
[3];
2938 if (tmp64
> fstar
.w
[2])
2941 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
2942 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
2943 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
2944 // set the inexact flag
2945 *pfpsf
|= INEXACT_EXCEPTION
;
2946 } // else the result is exact
2947 } else { // the result is inexact; f2* <= 1/2
2948 // set the inexact flag
2949 *pfpsf
|= INEXACT_EXCEPTION
;
2951 } else { // if 22 <= ind <= 33
2952 if (fstar
.w
[3] > onehalf128
[ind
- 1] ||
2953 (fstar
.w
[3] == onehalf128
[ind
- 1] &&
2954 (fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0]))) {
2955 // f2* > 1/2 and the result may be exact
2956 // Calculate f2* - 1/2
2957 tmp64
= fstar
.w
[3] - onehalf128
[ind
- 1];
2958 if (tmp64
|| fstar
.w
[2]
2959 || fstar
.w
[1] > ten2mk128trunc
[ind
- 1].w
[1]
2960 || (fstar
.w
[1] == ten2mk128trunc
[ind
- 1].w
[1]
2961 && fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[0])) {
2962 // set the inexact flag
2963 *pfpsf
|= INEXACT_EXCEPTION
;
2964 } // else the result is exact
2965 } else { // the result is inexact; f2* <= 1/2
2966 // set the inexact flag
2967 *pfpsf
|= INEXACT_EXCEPTION
;
2971 // if the result was a midpoint it was rounded away from zero
2976 } else if (exp
== 0) {
2978 // res = +/-C (exact)
2983 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19
2984 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer
2986 res
= -C1
.w
[0] * ten2k64
[exp
];
2988 res
= C1
.w
[0] * ten2k64
[exp
];