* gcc-interface/decl.c (gnat_to_gnu_field): Do not set the alignment
[official-gcc.git] / libgcc / config / libbid / bid128_to_int64.c
blob30bff698615cace0408eb9fdc168b228d92c64a4
1 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 /*****************************************************************************
27 * BID128_to_int64_rnint
28 ****************************************************************************/
30 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_rnint,
33 SINT64 res;
34 UINT64 x_sign;
35 UINT64 x_exp;
36 int exp; // unbiased exponent
37 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
38 UINT64 tmp64;
39 BID_UI64DOUBLE tmp1;
40 unsigned int x_nr_bits;
41 int q, ind, shift;
42 UINT128 C1, C;
43 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
44 UINT256 fstar;
45 UINT256 P256;
47 // unpack x
48 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
49 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
50 C1.w[1] = x.w[1] & MASK_COEFF;
51 C1.w[0] = x.w[0];
53 // check for NaN or Infinity
54 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
55 // x is special
56 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
57 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
58 // set invalid flag
59 *pfpsf |= INVALID_EXCEPTION;
60 // return Integer Indefinite
61 res = 0x8000000000000000ull;
62 } else { // x is QNaN
63 // set invalid flag
64 *pfpsf |= INVALID_EXCEPTION;
65 // return Integer Indefinite
66 res = 0x8000000000000000ull;
68 BID_RETURN (res);
69 } else { // x is not a NaN, so it must be infinity
70 if (!x_sign) { // x is +inf
71 // set invalid flag
72 *pfpsf |= INVALID_EXCEPTION;
73 // return Integer Indefinite
74 res = 0x8000000000000000ull;
75 } else { // x is -inf
76 // set invalid flag
77 *pfpsf |= INVALID_EXCEPTION;
78 // return Integer Indefinite
79 res = 0x8000000000000000ull;
81 BID_RETURN (res);
84 // check for non-canonical values (after the check for special values)
85 if ((C1.w[1] > 0x0001ed09bead87c0ull) ||
86 (C1.w[1] == 0x0001ed09bead87c0ull
87 && (C1.w[0] > 0x378d8e63ffffffffull))
88 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
89 res = 0x0000000000000000ull;
90 BID_RETURN (res);
91 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
92 // x is 0
93 res = 0x0000000000000000ull;
94 BID_RETURN (res);
95 } else { // x is not special and is not zero
97 // q = nr. of decimal digits in x
98 // determine first the nr. of bits in x
99 if (C1.w[1] == 0) {
100 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
101 // split the 64-bit value in two 32-bit halves to avoid rounding errors
102 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
103 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
104 x_nr_bits =
105 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
106 } else { // x < 2^32
107 tmp1.d = (double) (C1.w[0]); // exact conversion
108 x_nr_bits =
109 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
111 } else { // if x < 2^53
112 tmp1.d = (double) C1.w[0]; // exact conversion
113 x_nr_bits =
114 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
116 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
117 tmp1.d = (double) C1.w[1]; // exact conversion
118 x_nr_bits =
119 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
121 q = nr_digits[x_nr_bits - 1].digits;
122 if (q == 0) {
123 q = nr_digits[x_nr_bits - 1].digits1;
124 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
125 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
126 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
127 q++;
129 exp = (x_exp >> 49) - 6176;
130 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
131 // set invalid flag
132 *pfpsf |= INVALID_EXCEPTION;
133 // return Integer Indefinite
134 res = 0x8000000000000000ull;
135 BID_RETURN (res);
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) {
153 ; // C1 * 10^0 = C1
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])) {
158 // set invalid flag
159 *pfpsf |= INVALID_EXCEPTION;
160 // return Integer Indefinite
161 res = 0x8000000000000000ull;
162 BID_RETURN (res);
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) {
177 ; // C1 * 10^0 = C1
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])) {
182 // set invalid flag
183 *pfpsf |= INVALID_EXCEPTION;
184 // return Integer Indefinite
185 res = 0x8000000000000000ull;
186 BID_RETURN (res);
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;
196 C1.w[0] = x.w[0];
197 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
198 // return 0
199 res = 0x0000000000000000ull;
200 BID_RETURN (res);
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)
203 // res = 0
204 // else
205 // res = +/-1
206 ind = 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
212 } else { // n > 0
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
222 } else { // n > 0
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
233 tmp64 = C1.w[0];
234 if (ind <= 19) {
235 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
236 } else {
237 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
238 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
240 if (C1.w[0] < tmp64)
241 C1.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[]
246 // 1 <= x <= 33
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];
254 fstar.w[3] = 0;
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
259 Cstar.w[1] = 0;
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)
273 // else
274 // C* = floor(C*) (logical right shift; C has p decimal digits,
275 // correct by Property 1)
276 // n = C* * 10^(e+x)
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
281 Cstar.w[0] =
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]
301 if (x_sign)
302 res = -Cstar.w[0];
303 else
304 res = Cstar.w[0];
305 } else if (exp == 0) {
306 // 1 <= q <= 19
307 // res = +/-C (exact)
308 if (x_sign)
309 res = -C1.w[0];
310 else
311 res = C1.w[0];
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
314 if (x_sign)
315 res = -C1.w[0] * ten2k64[exp];
316 else
317 res = C1.w[0] * ten2k64[exp];
322 BID_RETURN (res);
325 /*****************************************************************************
326 * BID128_to_int64_xrnint
327 ****************************************************************************/
329 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64,
330 bid128_to_int64_xrnint, x)
332 SINT64 res;
333 UINT64 x_sign;
334 UINT64 x_exp;
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;
338 BID_UI64DOUBLE tmp1;
339 unsigned int x_nr_bits;
340 int q, ind, shift;
341 UINT128 C1, C;
342 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
343 UINT256 fstar;
344 UINT256 P256;
346 // unpack x
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;
350 C1.w[0] = x.w[0];
352 // check for NaN or Infinity
353 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
354 // x is 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
357 // set invalid flag
358 *pfpsf |= INVALID_EXCEPTION;
359 // return Integer Indefinite
360 res = 0x8000000000000000ull;
361 } else { // x is QNaN
362 // set invalid flag
363 *pfpsf |= INVALID_EXCEPTION;
364 // return Integer Indefinite
365 res = 0x8000000000000000ull;
367 BID_RETURN (res);
368 } else { // x is not a NaN, so it must be infinity
369 if (!x_sign) { // x is +inf
370 // set invalid flag
371 *pfpsf |= INVALID_EXCEPTION;
372 // return Integer Indefinite
373 res = 0x8000000000000000ull;
374 } else { // x is -inf
375 // set invalid flag
376 *pfpsf |= INVALID_EXCEPTION;
377 // return Integer Indefinite
378 res = 0x8000000000000000ull;
380 BID_RETURN (res);
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;
389 BID_RETURN (res);
390 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
391 // x is 0
392 res = 0x0000000000000000ull;
393 BID_RETURN (res);
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
398 if (C1.w[1] == 0) {
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
403 x_nr_bits =
404 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
405 } else { // x < 2^32
406 tmp1.d = (double) (C1.w[0]); // exact conversion
407 x_nr_bits =
408 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
410 } else { // if x < 2^53
411 tmp1.d = (double) C1.w[0]; // exact conversion
412 x_nr_bits =
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
417 x_nr_bits =
418 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
420 q = nr_digits[x_nr_bits - 1].digits;
421 if (q == 0) {
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))
426 q++;
428 exp = (x_exp >> 49) - 6176;
429 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
430 // set invalid flag
431 *pfpsf |= INVALID_EXCEPTION;
432 // return Integer Indefinite
433 res = 0x8000000000000000ull;
434 BID_RETURN (res);
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) {
452 ; // C1 * 10^0 = C1
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])) {
457 // set invalid flag
458 *pfpsf |= INVALID_EXCEPTION;
459 // return Integer Indefinite
460 res = 0x8000000000000000ull;
461 BID_RETURN (res);
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) {
476 ; // C1 * 10^0 = C1
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])) {
481 // set invalid flag
482 *pfpsf |= INVALID_EXCEPTION;
483 // return Integer Indefinite
484 res = 0x8000000000000000ull;
485 BID_RETURN (res);
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;
495 C1.w[0] = x.w[0];
496 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
497 // set inexact flag
498 *pfpsf |= INEXACT_EXCEPTION;
499 // return 0
500 res = 0x0000000000000000ull;
501 BID_RETURN (res);
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)
504 // res = 0
505 // else
506 // res = +/-1
507 ind = 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
513 } else { // n > 0
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
523 } else { // n > 0
524 res = 0x0000000000000001ull; // return +1
527 // set inexact flag
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
536 tmp64 = C1.w[0];
537 if (ind <= 19) {
538 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
539 } else {
540 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
541 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
543 if (C1.w[0] < tmp64)
544 C1.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[]
549 // 1 <= x <= 33
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];
557 fstar.w[3] = 0;
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
562 Cstar.w[1] = 0;
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)
576 // else
577 // C* = floor(C*) (logical right shift; C has p decimal digits,
578 // correct by Property 1)
579 // n = C* * 10^(e+x)
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
584 Cstar.w[0] =
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
595 if (ind - 1 <= 2) {
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];
619 tmp64A = fstar.w[3];
620 if (tmp64 > fstar.w[2])
621 tmp64A--;
622 if (tmp64A || tmp64
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]
667 if (x_sign)
668 res = -Cstar.w[0];
669 else
670 res = Cstar.w[0];
671 } else if (exp == 0) {
672 // 1 <= q <= 19
673 // res = +/-C (exact)
674 if (x_sign)
675 res = -C1.w[0];
676 else
677 res = C1.w[0];
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
680 if (x_sign)
681 res = -C1.w[0] * ten2k64[exp];
682 else
683 res = C1.w[0] * ten2k64[exp];
688 BID_RETURN (res);
691 /*****************************************************************************
692 * BID128_to_int64_floor
693 ****************************************************************************/
695 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_floor,
698 SINT64 res;
699 UINT64 x_sign;
700 UINT64 x_exp;
701 int exp; // unbiased exponent
702 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
703 BID_UI64DOUBLE tmp1;
704 unsigned int x_nr_bits;
705 int q, ind, shift;
706 UINT128 C1, C;
707 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
708 UINT256 fstar;
709 UINT256 P256;
711 // unpack x
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;
715 C1.w[0] = x.w[0];
717 // check for NaN or Infinity
718 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
719 // x is 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
722 // set invalid flag
723 *pfpsf |= INVALID_EXCEPTION;
724 // return Integer Indefinite
725 res = 0x8000000000000000ull;
726 } else { // x is QNaN
727 // set invalid flag
728 *pfpsf |= INVALID_EXCEPTION;
729 // return Integer Indefinite
730 res = 0x8000000000000000ull;
732 BID_RETURN (res);
733 } else { // x is not a NaN, so it must be infinity
734 if (!x_sign) { // x is +inf
735 // set invalid flag
736 *pfpsf |= INVALID_EXCEPTION;
737 // return Integer Indefinite
738 res = 0x8000000000000000ull;
739 } else { // x is -inf
740 // set invalid flag
741 *pfpsf |= INVALID_EXCEPTION;
742 // return Integer Indefinite
743 res = 0x8000000000000000ull;
745 BID_RETURN (res);
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;
754 BID_RETURN (res);
755 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
756 // x is 0
757 res = 0x0000000000000000ull;
758 BID_RETURN (res);
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
763 if (C1.w[1] == 0) {
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
768 x_nr_bits =
769 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
770 } else { // x < 2^32
771 tmp1.d = (double) (C1.w[0]); // exact conversion
772 x_nr_bits =
773 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
775 } else { // if x < 2^53
776 tmp1.d = (double) C1.w[0]; // exact conversion
777 x_nr_bits =
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
782 x_nr_bits =
783 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
785 q = nr_digits[x_nr_bits - 1].digits;
786 if (q == 0) {
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))
791 q++;
793 exp = (x_exp >> 49) - 6176;
795 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
796 // set invalid flag
797 *pfpsf |= INVALID_EXCEPTION;
798 // return Integer Indefinite
799 res = 0x8000000000000000ull;
800 BID_RETURN (res);
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) {
818 ; // C1 * 10^0 = C1
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])) {
823 // set invalid flag
824 *pfpsf |= INVALID_EXCEPTION;
825 // return Integer Indefinite
826 res = 0x8000000000000000ull;
827 BID_RETURN (res);
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) {
842 ; // C1 * 10^0 = C1
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])) {
847 // set invalid flag
848 *pfpsf |= INVALID_EXCEPTION;
849 // return Integer Indefinite
850 res = 0x8000000000000000ull;
851 BID_RETURN (res);
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;
861 C1.w[0] = x.w[0];
862 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
863 // return -1 or 0
864 if (x_sign)
865 res = 0xffffffffffffffffull;
866 else
867 res = 0x0000000000000000ull;
868 BID_RETURN (res);
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[]
880 // 1 <= x <= 33
881 // kx = 10^(-x) = ten2mk128[ind - 1]
882 // C* = C1 * 10^(-x)
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];
888 fstar.w[3] = 0;
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
893 Cstar.w[1] = 0;
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)
904 // n = C* * 10^(e+x)
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
909 Cstar.w[0] =
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
922 if (ind - 1 <= 2) {
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
927 Cstar.w[0]++;
928 if (Cstar.w[0] == 0x0)
929 Cstar.w[1]++;
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
937 Cstar.w[0]++;
938 if (Cstar.w[0] == 0x0)
939 Cstar.w[1]++;
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
948 Cstar.w[0]++;
949 if (Cstar.w[0] == 0x0)
950 Cstar.w[1]++;
952 } // else the result is exact
955 if (x_sign)
956 res = -Cstar.w[0];
957 else
958 res = Cstar.w[0];
959 } else if (exp == 0) {
960 // 1 <= q <= 19
961 // res = +/-C (exact)
962 if (x_sign)
963 res = -C1.w[0];
964 else
965 res = C1.w[0];
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
968 if (x_sign)
969 res = -C1.w[0] * ten2k64[exp];
970 else
971 res = C1.w[0] * ten2k64[exp];
976 BID_RETURN (res);
979 /*****************************************************************************
980 * BID128_to_int64_xfloor
981 ****************************************************************************/
983 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64,
984 bid128_to_int64_xfloor, x)
986 SINT64 res;
987 UINT64 x_sign;
988 UINT64 x_exp;
989 int exp; // unbiased exponent
990 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
991 BID_UI64DOUBLE tmp1;
992 unsigned int x_nr_bits;
993 int q, ind, shift;
994 UINT128 C1, C;
995 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
996 UINT256 fstar;
997 UINT256 P256;
999 // unpack x
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;
1003 C1.w[0] = x.w[0];
1005 // check for NaN or Infinity
1006 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1007 // x is 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
1010 // set invalid flag
1011 *pfpsf |= INVALID_EXCEPTION;
1012 // return Integer Indefinite
1013 res = 0x8000000000000000ull;
1014 } else { // x is QNaN
1015 // set invalid flag
1016 *pfpsf |= INVALID_EXCEPTION;
1017 // return Integer Indefinite
1018 res = 0x8000000000000000ull;
1020 BID_RETURN (res);
1021 } else { // x is not a NaN, so it must be infinity
1022 if (!x_sign) { // x is +inf
1023 // set invalid flag
1024 *pfpsf |= INVALID_EXCEPTION;
1025 // return Integer Indefinite
1026 res = 0x8000000000000000ull;
1027 } else { // x is -inf
1028 // set invalid flag
1029 *pfpsf |= INVALID_EXCEPTION;
1030 // return Integer Indefinite
1031 res = 0x8000000000000000ull;
1033 BID_RETURN (res);
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;
1042 BID_RETURN (res);
1043 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1044 // x is 0
1045 res = 0x0000000000000000ull;
1046 BID_RETURN (res);
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
1051 if (C1.w[1] == 0) {
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
1056 x_nr_bits =
1057 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1058 } else { // x < 2^32
1059 tmp1.d = (double) (C1.w[0]); // exact conversion
1060 x_nr_bits =
1061 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1063 } else { // if x < 2^53
1064 tmp1.d = (double) C1.w[0]; // exact conversion
1065 x_nr_bits =
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
1070 x_nr_bits =
1071 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1073 q = nr_digits[x_nr_bits - 1].digits;
1074 if (q == 0) {
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))
1079 q++;
1081 exp = (x_exp >> 49) - 6176;
1082 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1083 // set invalid flag
1084 *pfpsf |= INVALID_EXCEPTION;
1085 // return Integer Indefinite
1086 res = 0x8000000000000000ull;
1087 BID_RETURN (res);
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) {
1105 ; // C1 * 10^0 = C1
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])) {
1110 // set invalid flag
1111 *pfpsf |= INVALID_EXCEPTION;
1112 // return Integer Indefinite
1113 res = 0x8000000000000000ull;
1114 BID_RETURN (res);
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) {
1129 ; // C1 * 10^0 = C1
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])) {
1134 // set invalid flag
1135 *pfpsf |= INVALID_EXCEPTION;
1136 // return Integer Indefinite
1137 res = 0x8000000000000000ull;
1138 BID_RETURN (res);
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;
1148 C1.w[0] = x.w[0];
1149 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1150 // set inexact flag
1151 *pfpsf |= INEXACT_EXCEPTION;
1152 // return -1 or 0
1153 if (x_sign)
1154 res = 0xffffffffffffffffull;
1155 else
1156 res = 0x0000000000000000ull;
1157 BID_RETURN (res);
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[]
1169 // 1 <= x <= 33
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];
1177 fstar.w[3] = 0;
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
1182 Cstar.w[1] = 0;
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
1198 Cstar.w[0] =
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
1211 if (ind - 1 <= 2) {
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
1216 Cstar.w[0]++;
1217 if (Cstar.w[0] == 0x0)
1218 Cstar.w[1]++;
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
1228 Cstar.w[0]++;
1229 if (Cstar.w[0] == 0x0)
1230 Cstar.w[1]++;
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
1241 Cstar.w[0]++;
1242 if (Cstar.w[0] == 0x0)
1243 Cstar.w[1]++;
1245 // set the inexact flag
1246 *pfpsf |= INEXACT_EXCEPTION;
1247 } // else the result is exact
1250 if (x_sign)
1251 res = -Cstar.w[0];
1252 else
1253 res = Cstar.w[0];
1254 } else if (exp == 0) {
1255 // 1 <= q <= 19
1256 // res = +/-C (exact)
1257 if (x_sign)
1258 res = -C1.w[0];
1259 else
1260 res = C1.w[0];
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
1263 if (x_sign)
1264 res = -C1.w[0] * ten2k64[exp];
1265 else
1266 res = C1.w[0] * ten2k64[exp];
1271 BID_RETURN (res);
1274 /*****************************************************************************
1275 * BID128_to_int64_ceil
1276 ****************************************************************************/
1278 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_ceil,
1281 SINT64 res;
1282 UINT64 x_sign;
1283 UINT64 x_exp;
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;
1288 int q, ind, shift;
1289 UINT128 C1, C;
1290 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1291 UINT256 fstar;
1292 UINT256 P256;
1294 // unpack x
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;
1298 C1.w[0] = x.w[0];
1300 // check for NaN or Infinity
1301 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1302 // x is 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
1305 // set invalid flag
1306 *pfpsf |= INVALID_EXCEPTION;
1307 // return Integer Indefinite
1308 res = 0x8000000000000000ull;
1309 } else { // x is QNaN
1310 // set invalid flag
1311 *pfpsf |= INVALID_EXCEPTION;
1312 // return Integer Indefinite
1313 res = 0x8000000000000000ull;
1315 BID_RETURN (res);
1316 } else { // x is not a NaN, so it must be infinity
1317 if (!x_sign) { // x is +inf
1318 // set invalid flag
1319 *pfpsf |= INVALID_EXCEPTION;
1320 // return Integer Indefinite
1321 res = 0x8000000000000000ull;
1322 } else { // x is -inf
1323 // set invalid flag
1324 *pfpsf |= INVALID_EXCEPTION;
1325 // return Integer Indefinite
1326 res = 0x8000000000000000ull;
1328 BID_RETURN (res);
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;
1337 BID_RETURN (res);
1338 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1339 // x is 0
1340 res = 0x0000000000000000ull;
1341 BID_RETURN (res);
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
1346 if (C1.w[1] == 0) {
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
1351 x_nr_bits =
1352 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1353 } else { // x < 2^32
1354 tmp1.d = (double) (C1.w[0]); // exact conversion
1355 x_nr_bits =
1356 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1358 } else { // if x < 2^53
1359 tmp1.d = (double) C1.w[0]; // exact conversion
1360 x_nr_bits =
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
1365 x_nr_bits =
1366 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1368 q = nr_digits[x_nr_bits - 1].digits;
1369 if (q == 0) {
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))
1374 q++;
1376 exp = (x_exp >> 49) - 6176;
1377 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1378 // set invalid flag
1379 *pfpsf |= INVALID_EXCEPTION;
1380 // return Integer Indefinite
1381 res = 0x8000000000000000ull;
1382 BID_RETURN (res);
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) {
1400 ; // C1 * 10^0 = C1
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])) {
1405 // set invalid flag
1406 *pfpsf |= INVALID_EXCEPTION;
1407 // return Integer Indefinite
1408 res = 0x8000000000000000ull;
1409 BID_RETURN (res);
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) {
1424 ; // C1 * 10^0 = C1
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])) {
1429 // set invalid flag
1430 *pfpsf |= INVALID_EXCEPTION;
1431 // return Integer Indefinite
1432 res = 0x8000000000000000ull;
1433 BID_RETURN (res);
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;
1443 C1.w[0] = x.w[0];
1444 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1445 // return 0 or 1
1446 if (x_sign)
1447 res = 0x0000000000000000ull;
1448 else
1449 res = 0x0000000000000001ull;
1450 BID_RETURN (res);
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[]
1462 // 1 <= x <= 33
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];
1470 fstar.w[3] = 0;
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
1475 Cstar.w[1] = 0;
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
1491 Cstar.w[0] =
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
1504 if (ind - 1 <= 2) {
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
1509 Cstar.w[0]++;
1510 if (Cstar.w[0] == 0x0)
1511 Cstar.w[1]++;
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
1519 Cstar.w[0]++;
1520 if (Cstar.w[0] == 0x0)
1521 Cstar.w[1]++;
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
1530 Cstar.w[0]++;
1531 if (Cstar.w[0] == 0x0)
1532 Cstar.w[1]++;
1534 } // else the result is exact
1536 if (x_sign)
1537 res = -Cstar.w[0];
1538 else
1539 res = Cstar.w[0];
1540 } else if (exp == 0) {
1541 // 1 <= q <= 19
1542 // res = +/-C (exact)
1543 if (x_sign)
1544 res = -C1.w[0];
1545 else
1546 res = C1.w[0];
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
1549 if (x_sign)
1550 res = -C1.w[0] * ten2k64[exp];
1551 else
1552 res = C1.w[0] * ten2k64[exp];
1557 BID_RETURN (res);
1560 /*****************************************************************************
1561 * BID128_to_int64_xceil
1562 ****************************************************************************/
1564 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_xceil,
1567 SINT64 res;
1568 UINT64 x_sign;
1569 UINT64 x_exp;
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;
1574 int q, ind, shift;
1575 UINT128 C1, C;
1576 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1577 UINT256 fstar;
1578 UINT256 P256;
1580 // unpack x
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;
1584 C1.w[0] = x.w[0];
1586 // check for NaN or Infinity
1587 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1588 // x is 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
1591 // set invalid flag
1592 *pfpsf |= INVALID_EXCEPTION;
1593 // return Integer Indefinite
1594 res = 0x8000000000000000ull;
1595 } else { // x is QNaN
1596 // set invalid flag
1597 *pfpsf |= INVALID_EXCEPTION;
1598 // return Integer Indefinite
1599 res = 0x8000000000000000ull;
1601 BID_RETURN (res);
1602 } else { // x is not a NaN, so it must be infinity
1603 if (!x_sign) { // x is +inf
1604 // set invalid flag
1605 *pfpsf |= INVALID_EXCEPTION;
1606 // return Integer Indefinite
1607 res = 0x8000000000000000ull;
1608 } else { // x is -inf
1609 // set invalid flag
1610 *pfpsf |= INVALID_EXCEPTION;
1611 // return Integer Indefinite
1612 res = 0x8000000000000000ull;
1614 BID_RETURN (res);
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;
1623 BID_RETURN (res);
1624 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1625 // x is 0
1626 res = 0x0000000000000000ull;
1627 BID_RETURN (res);
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
1632 if (C1.w[1] == 0) {
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
1637 x_nr_bits =
1638 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1639 } else { // x < 2^32
1640 tmp1.d = (double) (C1.w[0]); // exact conversion
1641 x_nr_bits =
1642 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1644 } else { // if x < 2^53
1645 tmp1.d = (double) C1.w[0]; // exact conversion
1646 x_nr_bits =
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
1651 x_nr_bits =
1652 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1654 q = nr_digits[x_nr_bits - 1].digits;
1655 if (q == 0) {
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))
1660 q++;
1662 exp = (x_exp >> 49) - 6176;
1663 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1664 // set invalid flag
1665 *pfpsf |= INVALID_EXCEPTION;
1666 // return Integer Indefinite
1667 res = 0x8000000000000000ull;
1668 BID_RETURN (res);
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) {
1686 ; // C1 * 10^0 = C1
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])) {
1691 // set invalid flag
1692 *pfpsf |= INVALID_EXCEPTION;
1693 // return Integer Indefinite
1694 res = 0x8000000000000000ull;
1695 BID_RETURN (res);
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) {
1710 ; // C1 * 10^0 = C1
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])) {
1715 // set invalid flag
1716 *pfpsf |= INVALID_EXCEPTION;
1717 // return Integer Indefinite
1718 res = 0x8000000000000000ull;
1719 BID_RETURN (res);
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;
1729 C1.w[0] = x.w[0];
1730 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
1731 // set inexact flag
1732 *pfpsf |= INEXACT_EXCEPTION;
1733 // return 0 or 1
1734 if (x_sign)
1735 res = 0x0000000000000000ull;
1736 else
1737 res = 0x0000000000000001ull;
1738 BID_RETURN (res);
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[]
1750 // 1 <= x <= 33
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];
1758 fstar.w[3] = 0;
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
1763 Cstar.w[1] = 0;
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
1779 Cstar.w[0] =
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
1792 if (ind - 1 <= 2) {
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
1797 Cstar.w[0]++;
1798 if (Cstar.w[0] == 0x0)
1799 Cstar.w[1]++;
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
1809 Cstar.w[0]++;
1810 if (Cstar.w[0] == 0x0)
1811 Cstar.w[1]++;
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
1822 Cstar.w[0]++;
1823 if (Cstar.w[0] == 0x0)
1824 Cstar.w[1]++;
1826 // set the inexact flag
1827 *pfpsf |= INEXACT_EXCEPTION;
1828 } // else the result is exact
1831 if (x_sign)
1832 res = -Cstar.w[0];
1833 else
1834 res = Cstar.w[0];
1835 } else if (exp == 0) {
1836 // 1 <= q <= 19
1837 // res = +/-C (exact)
1838 if (x_sign)
1839 res = -C1.w[0];
1840 else
1841 res = C1.w[0];
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
1844 if (x_sign)
1845 res = -C1.w[0] * ten2k64[exp];
1846 else
1847 res = C1.w[0] * ten2k64[exp];
1852 BID_RETURN (res);
1855 /*****************************************************************************
1856 * BID128_to_int64_int
1857 ****************************************************************************/
1859 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_int,
1862 SINT64 res;
1863 UINT64 x_sign;
1864 UINT64 x_exp;
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;
1869 int q, ind, shift;
1870 UINT128 C1, C;
1871 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
1872 UINT256 P256;
1874 // unpack x
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;
1878 C1.w[0] = x.w[0];
1880 // check for NaN or Infinity
1881 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
1882 // x is 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
1885 // set invalid flag
1886 *pfpsf |= INVALID_EXCEPTION;
1887 // return Integer Indefinite
1888 res = 0x8000000000000000ull;
1889 } else { // x is QNaN
1890 // set invalid flag
1891 *pfpsf |= INVALID_EXCEPTION;
1892 // return Integer Indefinite
1893 res = 0x8000000000000000ull;
1895 BID_RETURN (res);
1896 } else { // x is not a NaN, so it must be infinity
1897 if (!x_sign) { // x is +inf
1898 // set invalid flag
1899 *pfpsf |= INVALID_EXCEPTION;
1900 // return Integer Indefinite
1901 res = 0x8000000000000000ull;
1902 } else { // x is -inf
1903 // set invalid flag
1904 *pfpsf |= INVALID_EXCEPTION;
1905 // return Integer Indefinite
1906 res = 0x8000000000000000ull;
1908 BID_RETURN (res);
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;
1917 BID_RETURN (res);
1918 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
1919 // x is 0
1920 res = 0x0000000000000000ull;
1921 BID_RETURN (res);
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
1926 if (C1.w[1] == 0) {
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
1931 x_nr_bits =
1932 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1933 } else { // x < 2^32
1934 tmp1.d = (double) (C1.w[0]); // exact conversion
1935 x_nr_bits =
1936 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1938 } else { // if x < 2^53
1939 tmp1.d = (double) C1.w[0]; // exact conversion
1940 x_nr_bits =
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
1945 x_nr_bits =
1946 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1948 q = nr_digits[x_nr_bits - 1].digits;
1949 if (q == 0) {
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))
1954 q++;
1956 exp = (x_exp >> 49) - 6176;
1957 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1958 // set invalid flag
1959 *pfpsf |= INVALID_EXCEPTION;
1960 // return Integer Indefinite
1961 res = 0x8000000000000000ull;
1962 BID_RETURN (res);
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) {
1980 ; // C1 * 10^0 = C1
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])) {
1985 // set invalid flag
1986 *pfpsf |= INVALID_EXCEPTION;
1987 // return Integer Indefinite
1988 res = 0x8000000000000000ull;
1989 BID_RETURN (res);
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) {
2004 ; // C1 * 10^0 = C1
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])) {
2009 // set invalid flag
2010 *pfpsf |= INVALID_EXCEPTION;
2011 // return Integer Indefinite
2012 res = 0x8000000000000000ull;
2013 BID_RETURN (res);
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;
2023 C1.w[0] = x.w[0];
2024 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2025 // return 0
2026 res = 0x0000000000000000ull;
2027 BID_RETURN (res);
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[]
2039 // 1 <= x <= 33
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
2048 Cstar.w[1] = 0;
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
2060 Cstar.w[0] =
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
2066 if (x_sign)
2067 res = -Cstar.w[0];
2068 else
2069 res = Cstar.w[0];
2070 } else if (exp == 0) {
2071 // 1 <= q <= 19
2072 // res = +/-C (exact)
2073 if (x_sign)
2074 res = -C1.w[0];
2075 else
2076 res = C1.w[0];
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
2079 if (x_sign)
2080 res = -C1.w[0] * ten2k64[exp];
2081 else
2082 res = C1.w[0] * ten2k64[exp];
2087 BID_RETURN (res);
2090 /*****************************************************************************
2091 * BID128_to_xint64_xint
2092 ****************************************************************************/
2094 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_xint,
2097 SINT64 res;
2098 UINT64 x_sign;
2099 UINT64 x_exp;
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;
2104 int q, ind, shift;
2105 UINT128 C1, C;
2106 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2107 UINT256 fstar;
2108 UINT256 P256;
2110 // unpack x
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;
2114 C1.w[0] = x.w[0];
2116 // check for NaN or Infinity
2117 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2118 // x is 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
2121 // set invalid flag
2122 *pfpsf |= INVALID_EXCEPTION;
2123 // return Integer Indefinite
2124 res = 0x8000000000000000ull;
2125 } else { // x is QNaN
2126 // set invalid flag
2127 *pfpsf |= INVALID_EXCEPTION;
2128 // return Integer Indefinite
2129 res = 0x8000000000000000ull;
2131 BID_RETURN (res);
2132 } else { // x is not a NaN, so it must be infinity
2133 if (!x_sign) { // x is +inf
2134 // set invalid flag
2135 *pfpsf |= INVALID_EXCEPTION;
2136 // return Integer Indefinite
2137 res = 0x8000000000000000ull;
2138 } else { // x is -inf
2139 // set invalid flag
2140 *pfpsf |= INVALID_EXCEPTION;
2141 // return Integer Indefinite
2142 res = 0x8000000000000000ull;
2144 BID_RETURN (res);
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;
2153 BID_RETURN (res);
2154 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2155 // x is 0
2156 res = 0x0000000000000000ull;
2157 BID_RETURN (res);
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
2162 if (C1.w[1] == 0) {
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
2167 x_nr_bits =
2168 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2169 } else { // x < 2^32
2170 tmp1.d = (double) (C1.w[0]); // exact conversion
2171 x_nr_bits =
2172 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2174 } else { // if x < 2^53
2175 tmp1.d = (double) C1.w[0]; // exact conversion
2176 x_nr_bits =
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
2181 x_nr_bits =
2182 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2184 q = nr_digits[x_nr_bits - 1].digits;
2185 if (q == 0) {
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))
2190 q++;
2192 exp = (x_exp >> 49) - 6176;
2193 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2194 // set invalid flag
2195 *pfpsf |= INVALID_EXCEPTION;
2196 // return Integer Indefinite
2197 res = 0x8000000000000000ull;
2198 BID_RETURN (res);
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) {
2216 ; // C1 * 10^0 = C1
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])) {
2221 // set invalid flag
2222 *pfpsf |= INVALID_EXCEPTION;
2223 // return Integer Indefinite
2224 res = 0x8000000000000000ull;
2225 BID_RETURN (res);
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) {
2240 ; // C1 * 10^0 = C1
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])) {
2245 // set invalid flag
2246 *pfpsf |= INVALID_EXCEPTION;
2247 // return Integer Indefinite
2248 res = 0x8000000000000000ull;
2249 BID_RETURN (res);
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;
2259 C1.w[0] = x.w[0];
2260 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1)
2261 // set inexact flag
2262 *pfpsf |= INEXACT_EXCEPTION;
2263 // return 0
2264 res = 0x0000000000000000ull;
2265 BID_RETURN (res);
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[]
2277 // 1 <= x <= 33
2278 // kx = 10^(-x) = ten2mk128[ind - 1]
2279 // C* = C1 * 10^(-x)
2280 // the approximation of 10^(-x) was rounded up to 118 bits
2281 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
2282 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21
2283 Cstar.w[1] = P256.w[3];
2284 Cstar.w[0] = P256.w[2];
2285 fstar.w[3] = 0;
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
2290 Cstar.w[1] = 0;
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
2306 Cstar.w[0] =
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
2317 if (ind - 1 <= 2) {
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;
2341 if (x_sign)
2342 res = -Cstar.w[0];
2343 else
2344 res = Cstar.w[0];
2345 } else if (exp == 0) {
2346 // 1 <= q <= 19
2347 // res = +/-C (exact)
2348 if (x_sign)
2349 res = -C1.w[0];
2350 else
2351 res = C1.w[0];
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
2354 if (x_sign)
2355 res = -C1.w[0] * ten2k64[exp];
2356 else
2357 res = C1.w[0] * ten2k64[exp];
2362 BID_RETURN (res);
2365 /*****************************************************************************
2366 * BID128_to_int64_rninta
2367 ****************************************************************************/
2369 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64,
2370 bid128_to_int64_rninta, x)
2372 SINT64 res;
2373 UINT64 x_sign;
2374 UINT64 x_exp;
2375 int exp; // unbiased exponent
2376 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
2377 UINT64 tmp64;
2378 BID_UI64DOUBLE tmp1;
2379 unsigned int x_nr_bits;
2380 int q, ind, shift;
2381 UINT128 C1, C;
2382 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2383 UINT256 P256;
2385 // unpack x
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;
2389 C1.w[0] = x.w[0];
2391 // check for NaN or Infinity
2392 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2393 // x is 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
2396 // set invalid flag
2397 *pfpsf |= INVALID_EXCEPTION;
2398 // return Integer Indefinite
2399 res = 0x8000000000000000ull;
2400 } else { // x is QNaN
2401 // set invalid flag
2402 *pfpsf |= INVALID_EXCEPTION;
2403 // return Integer Indefinite
2404 res = 0x8000000000000000ull;
2406 BID_RETURN (res);
2407 } else { // x is not a NaN, so it must be infinity
2408 if (!x_sign) { // x is +inf
2409 // set invalid flag
2410 *pfpsf |= INVALID_EXCEPTION;
2411 // return Integer Indefinite
2412 res = 0x8000000000000000ull;
2413 } else { // x is -inf
2414 // set invalid flag
2415 *pfpsf |= INVALID_EXCEPTION;
2416 // return Integer Indefinite
2417 res = 0x8000000000000000ull;
2419 BID_RETURN (res);
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;
2428 BID_RETURN (res);
2429 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2430 // x is 0
2431 res = 0x0000000000000000ull;
2432 BID_RETURN (res);
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
2437 if (C1.w[1] == 0) {
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
2442 x_nr_bits =
2443 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2444 } else { // x < 2^32
2445 tmp1.d = (double) (C1.w[0]); // exact conversion
2446 x_nr_bits =
2447 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2449 } else { // if x < 2^53
2450 tmp1.d = (double) C1.w[0]; // exact conversion
2451 x_nr_bits =
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
2456 x_nr_bits =
2457 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2459 q = nr_digits[x_nr_bits - 1].digits;
2460 if (q == 0) {
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))
2465 q++;
2467 exp = (x_exp >> 49) - 6176;
2468 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2469 // set invalid flag
2470 *pfpsf |= INVALID_EXCEPTION;
2471 // return Integer Indefinite
2472 res = 0x8000000000000000ull;
2473 BID_RETURN (res);
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) {
2491 ; // C1 * 10^0 = C1
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])) {
2496 // set invalid flag
2497 *pfpsf |= INVALID_EXCEPTION;
2498 // return Integer Indefinite
2499 res = 0x8000000000000000ull;
2500 BID_RETURN (res);
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) {
2515 ; // C1 * 10^0 = C1
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])) {
2520 // set invalid flag
2521 *pfpsf |= INVALID_EXCEPTION;
2522 // return Integer Indefinite
2523 res = 0x8000000000000000ull;
2524 BID_RETURN (res);
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;
2534 C1.w[0] = x.w[0];
2535 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2536 // return 0
2537 res = 0x0000000000000000ull;
2538 BID_RETURN (res);
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)
2541 // res = 0
2542 // else
2543 // res = +/-1
2544 ind = 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
2550 } else { // n > 0
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
2560 } else { // n > 0
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
2571 tmp64 = C1.w[0];
2572 if (ind <= 19) {
2573 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
2574 } else {
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)
2579 C1.w[1]++;
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[]
2584 // 1 <= x <= 33
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
2593 Cstar.w[1] = 0;
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)
2603 // else
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
2611 Cstar.w[0] =
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
2619 if (x_sign)
2620 res = -Cstar.w[0];
2621 else
2622 res = Cstar.w[0];
2623 } else if (exp == 0) {
2624 // 1 <= q <= 19
2625 // res = +/-C (exact)
2626 if (x_sign)
2627 res = -C1.w[0];
2628 else
2629 res = C1.w[0];
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
2632 if (x_sign)
2633 res = -C1.w[0] * ten2k64[exp];
2634 else
2635 res = C1.w[0] * ten2k64[exp];
2640 BID_RETURN (res);
2643 /*****************************************************************************
2644 * BID128_to_int64_xrninta
2645 ****************************************************************************/
2647 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64,
2648 bid128_to_int64_xrninta, x)
2650 SINT64 res;
2651 UINT64 x_sign;
2652 UINT64 x_exp;
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;
2658 int q, ind, shift;
2659 UINT128 C1, C;
2660 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits
2661 UINT256 fstar;
2662 UINT256 P256;
2664 // unpack x
2665 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
2666 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
2667 C1.w[1] = x.w[1] & MASK_COEFF;
2668 C1.w[0] = x.w[0];
2670 // check for NaN or Infinity
2671 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
2672 // x is special
2673 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
2674 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
2675 // set invalid flag
2676 *pfpsf |= INVALID_EXCEPTION;
2677 // return Integer Indefinite
2678 res = 0x8000000000000000ull;
2679 } else { // x is QNaN
2680 // set invalid flag
2681 *pfpsf |= INVALID_EXCEPTION;
2682 // return Integer Indefinite
2683 res = 0x8000000000000000ull;
2685 BID_RETURN (res);
2686 } else { // x is not a NaN, so it must be infinity
2687 if (!x_sign) { // x is +inf
2688 // set invalid flag
2689 *pfpsf |= INVALID_EXCEPTION;
2690 // return Integer Indefinite
2691 res = 0x8000000000000000ull;
2692 } else { // x is -inf
2693 // set invalid flag
2694 *pfpsf |= INVALID_EXCEPTION;
2695 // return Integer Indefinite
2696 res = 0x8000000000000000ull;
2698 BID_RETURN (res);
2701 // check for non-canonical values (after the check for special values)
2702 if ((C1.w[1] > 0x0001ed09bead87c0ull)
2703 || (C1.w[1] == 0x0001ed09bead87c0ull
2704 && (C1.w[0] > 0x378d8e63ffffffffull))
2705 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
2706 res = 0x0000000000000000ull;
2707 BID_RETURN (res);
2708 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
2709 // x is 0
2710 res = 0x0000000000000000ull;
2711 BID_RETURN (res);
2712 } else { // x is not special and is not zero
2714 // q = nr. of decimal digits in x
2715 // determine first the nr. of bits in x
2716 if (C1.w[1] == 0) {
2717 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
2718 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2719 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
2720 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
2721 x_nr_bits =
2722 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2723 } else { // x < 2^32
2724 tmp1.d = (double) (C1.w[0]); // exact conversion
2725 x_nr_bits =
2726 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2728 } else { // if x < 2^53
2729 tmp1.d = (double) C1.w[0]; // exact conversion
2730 x_nr_bits =
2731 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2733 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
2734 tmp1.d = (double) C1.w[1]; // exact conversion
2735 x_nr_bits =
2736 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2738 q = nr_digits[x_nr_bits - 1].digits;
2739 if (q == 0) {
2740 q = nr_digits[x_nr_bits - 1].digits1;
2741 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
2742 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
2743 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
2744 q++;
2746 exp = (x_exp >> 49) - 6176;
2747 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2748 // set invalid flag
2749 *pfpsf |= INVALID_EXCEPTION;
2750 // return Integer Indefinite
2751 res = 0x8000000000000000ull;
2752 BID_RETURN (res);
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) {
2770 ; // C1 * 10^0 = C1
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])) {
2775 // set invalid flag
2776 *pfpsf |= INVALID_EXCEPTION;
2777 // return Integer Indefinite
2778 res = 0x8000000000000000ull;
2779 BID_RETURN (res);
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) {
2794 ; // C1 * 10^0 = C1
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])) {
2799 // set invalid flag
2800 *pfpsf |= INVALID_EXCEPTION;
2801 // return Integer Indefinite
2802 res = 0x8000000000000000ull;
2803 BID_RETURN (res);
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;
2813 C1.w[0] = x.w[0];
2814 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2815 // set inexact flag
2816 *pfpsf |= INEXACT_EXCEPTION;
2817 // return 0
2818 res = 0x0000000000000000ull;
2819 BID_RETURN (res);
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)
2822 // res = 0
2823 // else
2824 // res = +/-1
2825 ind = 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
2831 } else { // n > 0
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
2841 } else { // n > 0
2842 res = 0x0000000000000001ull; // return +1
2845 // set inexact flag
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
2854 tmp64 = C1.w[0];
2855 if (ind <= 19) {
2856 C1.w[0] = C1.w[0] + midpoint64[ind - 1];
2857 } else {
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)
2862 C1.w[1]++;
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[]
2867 // 1 <= x <= 33
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];
2875 fstar.w[3] = 0;
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
2880 Cstar.w[1] = 0;
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)
2894 // else
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
2902 Cstar.w[0] =
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
2913 if (ind - 1 <= 2) {
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])
2939 tmp64A--;
2940 if (tmp64A || tmp64
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
2972 if (x_sign)
2973 res = -Cstar.w[0];
2974 else
2975 res = Cstar.w[0];
2976 } else if (exp == 0) {
2977 // 1 <= q <= 19
2978 // res = +/-C (exact)
2979 if (x_sign)
2980 res = -C1.w[0];
2981 else
2982 res = C1.w[0];
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
2985 if (x_sign)
2986 res = -C1.w[0] * ten2k64[exp];
2987 else
2988 res = C1.w[0] * ten2k64[exp];
2993 BID_RETURN (res);