1 /* Copyright (C) 2007-2023 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 /*****************************************************************************
27 * BID64_to_int64_rnint
28 ****************************************************************************/
30 #if DECIMAL_CALL_BY_REFERENCE
32 bid64_to_int64_rnint (SINT64
* pres
, UINT64
* px
33 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
38 bid64_to_int64_rnint (UINT64 x
39 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
45 int exp
; // unbiased exponent
46 // Note: C1 represents x_significand (UINT64)
48 unsigned int x_nr_bits
;
52 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
56 // check for NaN or Infinity
57 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
59 *pfpsf
|= INVALID_EXCEPTION
;
60 // return Integer Indefinite
61 res
= 0x8000000000000000ull
;
65 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
66 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
67 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
68 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
69 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
70 if (C1
> 9999999999999999ull) { // non-canonical
75 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
76 C1
= x
& MASK_BINARY_SIG1
;
79 // check for zeros (possibly from non-canonical values)
85 // x is not special and is not zero
87 // q = nr. of decimal digits in x (1 <= q <= 54)
88 // determine first the nr. of bits in x
89 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
90 // split the 64-bit value in two 32-bit halves to avoid rounding errors
91 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
92 tmp1
.d
= (double) (C1
>> 32); // exact conversion
94 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
96 tmp1
.d
= (double) C1
; // exact conversion
98 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
100 } else { // if x < 2^53
101 tmp1
.d
= (double) C1
; // exact conversion
103 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
105 q
= nr_digits
[x_nr_bits
- 1].digits
;
107 q
= nr_digits
[x_nr_bits
- 1].digits1
;
108 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
111 exp
= x_exp
- 398; // unbiased exponent
113 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
115 *pfpsf
|= INVALID_EXCEPTION
;
116 // return Integer Indefinite
117 res
= 0x8000000000000000ull
;
119 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
120 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
121 // so x rounded to an integer may or may not fit in a signed 64-bit int
122 // the cases that do not fit are identified here; the ones that fit
123 // fall through and will be handled with other cases further,
124 // under '1 <= q + exp <= 19'
125 if (x_sign
) { // if n < 0 and q + exp = 19
126 // if n < -2^63 - 1/2 then n is too large
127 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
128 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
129 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
130 // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
131 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
132 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
133 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
134 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] > 0x05ull
)) {
136 *pfpsf
|= INVALID_EXCEPTION
;
137 // return Integer Indefinite
138 res
= 0x8000000000000000ull
;
141 // else cases that can be rounded to a 64-bit int fall through
142 // to '1 <= q + exp <= 19'
143 } else { // if n > 0 and q + exp = 19
144 // if n >= 2^63 - 1/2 then n is too large
145 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
146 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
147 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
148 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
149 C
.w
[1] = 0x0000000000000004ull
;
150 C
.w
[0] = 0xfffffffffffffffbull
;
151 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
152 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
153 if (C
.w
[1] > 0x04ull
||
154 (C
.w
[1] == 0x04ull
&& C
.w
[0] >= 0xfffffffffffffffbull
)) {
156 *pfpsf
|= INVALID_EXCEPTION
;
157 // return Integer Indefinite
158 res
= 0x8000000000000000ull
;
161 // else cases that can be rounded to a 64-bit int fall through
162 // to '1 <= q + exp <= 19'
163 } // end else if n > 0 and q + exp = 19
164 } // end else if ((q + exp) == 19)
166 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
167 // Note: some of the cases tested for above fall through to this point
168 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
170 res
= 0x0000000000000000ull
;
172 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
173 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
177 ind
= q
- 1; // 0 <= ind <= 15
178 if (C1
<= midpoint64
[ind
]) {
179 res
= 0x0000000000000000ull
; // return 0
180 } else if (x_sign
) { // n < 0
181 res
= 0xffffffffffffffffull
; // return -1
183 res
= 0x0000000000000001ull
; // return +1
185 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
186 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
187 // to nearest to a 64-bit signed integer
188 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
189 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
190 // chop off ind digits from the lower part of C1
191 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
192 C1
= C1
+ midpoint64
[ind
- 1];
193 // calculate C* and f*
194 // C* is actually floor(C*) in this case
195 // C* and f* need shifting and masking, as shown by
196 // shiftright128[] and maskhigh128[]
198 // kx = 10^(-x) = ten2mk64[ind - 1]
199 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
200 // the approximation of 10^(-x) was rounded up to 54 bits
201 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
203 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
204 fstar
.w
[0] = P128
.w
[0];
205 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
206 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
207 // if (0 < f* < 10^(-x)) then the result is a midpoint
208 // if floor(C*) is even then C* = floor(C*) - logical right
209 // shift; C* has p decimal digits, correct by Prop. 1)
210 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
211 // shift; C* has p decimal digits, correct by Pr. 1)
213 // C* = floor(C*) (logical right shift; C has p decimal digits,
214 // correct by Property 1)
217 // shift right C* by Ex-64 = shiftright128[ind]
218 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
219 Cstar
= Cstar
>> shift
;
221 // if the result was a midpoint it was rounded away from zero, so
222 // it will need a correction
223 // check for midpoints
224 if ((fstar
.w
[1] == 0) && fstar
.w
[0] &&
225 (fstar
.w
[0] <= ten2mk128trunc
[ind
- 1].w
[1])) {
226 // ten2mk128trunc[ind -1].w[1] is identical to
227 // ten2mk128[ind -1].w[1]
228 // the result is a midpoint; round to nearest
229 if (Cstar
& 0x01) { // Cstar is odd; MP in [EVEN, ODD]
230 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
231 Cstar
--; // Cstar is now even
232 } // else MP in [ODD, EVEN]
238 } else if (exp
== 0) {
240 // res = +/-C (exact)
245 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
246 // (the upper limit of 20 on q + exp is due to the fact that
247 // +/-C * 10^exp is guaranteed to fit in 64 bits)
248 // res = +/-C * 10^exp (exact)
250 res
= -C1
* ten2k64
[exp
];
252 res
= C1
* ten2k64
[exp
];
258 /*****************************************************************************
259 * BID64_to_int64_xrnint
260 ****************************************************************************/
262 #if DECIMAL_CALL_BY_REFERENCE
264 bid64_to_int64_xrnint (SINT64
* pres
, UINT64
* px
265 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
270 bid64_to_int64_xrnint (UINT64 x
271 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
277 int exp
; // unbiased exponent
278 // Note: C1 represents x_significand (UINT64)
281 unsigned int x_nr_bits
;
285 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
289 // check for NaN or Infinity
290 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
292 *pfpsf
|= INVALID_EXCEPTION
;
293 // return Integer Indefinite
294 res
= 0x8000000000000000ull
;
298 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
299 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
300 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
301 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
302 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
303 if (C1
> 9999999999999999ull) { // non-canonical
308 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
309 C1
= x
& MASK_BINARY_SIG1
;
312 // check for zeros (possibly from non-canonical values)
318 // x is not special and is not zero
320 // q = nr. of decimal digits in x (1 <= q <= 54)
321 // determine first the nr. of bits in x
322 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
323 // split the 64-bit value in two 32-bit halves to avoid rounding errors
324 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
325 tmp1
.d
= (double) (C1
>> 32); // exact conversion
327 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
329 tmp1
.d
= (double) C1
; // exact conversion
331 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
333 } else { // if x < 2^53
334 tmp1
.d
= (double) C1
; // exact conversion
336 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
338 q
= nr_digits
[x_nr_bits
- 1].digits
;
340 q
= nr_digits
[x_nr_bits
- 1].digits1
;
341 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
344 exp
= x_exp
- 398; // unbiased exponent
346 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
348 *pfpsf
|= INVALID_EXCEPTION
;
349 // return Integer Indefinite
350 res
= 0x8000000000000000ull
;
352 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
353 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
354 // so x rounded to an integer may or may not fit in a signed 64-bit int
355 // the cases that do not fit are identified here; the ones that fit
356 // fall through and will be handled with other cases further,
357 // under '1 <= q + exp <= 19'
358 if (x_sign
) { // if n < 0 and q + exp = 19
359 // if n < -2^63 - 1/2 then n is too large
360 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
361 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
362 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
363 // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
364 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
365 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
366 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
367 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] > 0x05ull
)) {
369 *pfpsf
|= INVALID_EXCEPTION
;
370 // return Integer Indefinite
371 res
= 0x8000000000000000ull
;
374 // else cases that can be rounded to a 64-bit int fall through
375 // to '1 <= q + exp <= 19'
376 } else { // if n > 0 and q + exp = 19
377 // if n >= 2^63 - 1/2 then n is too large
378 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
379 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
380 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
381 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
382 C
.w
[1] = 0x0000000000000004ull
;
383 C
.w
[0] = 0xfffffffffffffffbull
;
384 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
385 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
386 if (C
.w
[1] > 0x04ull
||
387 (C
.w
[1] == 0x04ull
&& C
.w
[0] >= 0xfffffffffffffffbull
)) {
389 *pfpsf
|= INVALID_EXCEPTION
;
390 // return Integer Indefinite
391 res
= 0x8000000000000000ull
;
394 // else cases that can be rounded to a 64-bit int fall through
395 // to '1 <= q + exp <= 19'
396 } // end else if n > 0 and q + exp = 19
397 } // end else if ((q + exp) == 19)
399 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
400 // Note: some of the cases tested for above fall through to this point
401 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
403 *pfpsf
|= INEXACT_EXCEPTION
;
405 res
= 0x0000000000000000ull
;
407 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
408 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
412 ind
= q
- 1; // 0 <= ind <= 15
413 if (C1
<= midpoint64
[ind
]) {
414 res
= 0x0000000000000000ull
; // return 0
415 } else if (x_sign
) { // n < 0
416 res
= 0xffffffffffffffffull
; // return -1
418 res
= 0x0000000000000001ull
; // return +1
421 *pfpsf
|= INEXACT_EXCEPTION
;
422 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
423 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
424 // to nearest to a 64-bit signed integer
425 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
426 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
427 // chop off ind digits from the lower part of C1
428 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
429 C1
= C1
+ midpoint64
[ind
- 1];
430 // calculate C* and f*
431 // C* is actually floor(C*) in this case
432 // C* and f* need shifting and masking, as shown by
433 // shiftright128[] and maskhigh128[]
435 // kx = 10^(-x) = ten2mk64[ind - 1]
436 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
437 // the approximation of 10^(-x) was rounded up to 54 bits
438 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
440 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
441 fstar
.w
[0] = P128
.w
[0];
442 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
443 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
444 // if (0 < f* < 10^(-x)) then the result is a midpoint
445 // if floor(C*) is even then C* = floor(C*) - logical right
446 // shift; C* has p decimal digits, correct by Prop. 1)
447 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
448 // shift; C* has p decimal digits, correct by Pr. 1)
450 // C* = floor(C*) (logical right shift; C has p decimal digits,
451 // correct by Property 1)
454 // shift right C* by Ex-64 = shiftright128[ind]
455 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
456 Cstar
= Cstar
>> shift
;
457 // determine inexactness of the rounding of C*
458 // if (0 < f* - 1/2 < 10^(-x)) then
459 // the result is exact
460 // else // if (f* - 1/2 > T*) then
461 // the result is inexact
463 if (fstar
.w
[0] > 0x8000000000000000ull
) {
464 // f* > 1/2 and the result may be exact
465 tmp64
= fstar
.w
[0] - 0x8000000000000000ull
; // f* - 1/2
466 if ((tmp64
> ten2mk128trunc
[ind
- 1].w
[1])) {
467 // ten2mk128trunc[ind -1].w[1] is identical to
468 // ten2mk128[ind -1].w[1]
469 // set the inexact flag
470 *pfpsf
|= INEXACT_EXCEPTION
;
471 } // else the result is exact
472 } else { // the result is inexact; f2* <= 1/2
473 // set the inexact flag
474 *pfpsf
|= INEXACT_EXCEPTION
;
476 } else { // if 3 <= ind - 1 <= 14
477 if (fstar
.w
[1] > onehalf128
[ind
- 1] ||
478 (fstar
.w
[1] == onehalf128
[ind
- 1] && fstar
.w
[0])) {
479 // f2* > 1/2 and the result may be exact
480 // Calculate f2* - 1/2
481 tmp64
= fstar
.w
[1] - onehalf128
[ind
- 1];
482 if (tmp64
|| fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
483 // ten2mk128trunc[ind -1].w[1] is identical to
484 // ten2mk128[ind -1].w[1]
485 // set the inexact flag
486 *pfpsf
|= INEXACT_EXCEPTION
;
487 } // else the result is exact
488 } else { // the result is inexact; f2* <= 1/2
489 // set the inexact flag
490 *pfpsf
|= INEXACT_EXCEPTION
;
494 // if the result was a midpoint it was rounded away from zero, so
495 // it will need a correction
496 // check for midpoints
497 if ((fstar
.w
[1] == 0) && fstar
.w
[0] &&
498 (fstar
.w
[0] <= ten2mk128trunc
[ind
- 1].w
[1])) {
499 // ten2mk128trunc[ind -1].w[1] is identical to
500 // ten2mk128[ind -1].w[1]
501 // the result is a midpoint; round to nearest
502 if (Cstar
& 0x01) { // Cstar is odd; MP in [EVEN, ODD]
503 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
504 Cstar
--; // Cstar is now even
505 } // else MP in [ODD, EVEN]
511 } else if (exp
== 0) {
513 // res = +/-C (exact)
518 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
519 // (the upper limit of 20 on q + exp is due to the fact that
520 // +/-C * 10^exp is guaranteed to fit in 64 bits)
521 // res = +/-C * 10^exp (exact)
523 res
= -C1
* ten2k64
[exp
];
525 res
= C1
* ten2k64
[exp
];
531 /*****************************************************************************
532 * BID64_to_int64_floor
533 ****************************************************************************/
535 #if DECIMAL_CALL_BY_REFERENCE
537 bid64_to_int64_floor (SINT64
* pres
, UINT64
* px
538 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
543 bid64_to_int64_floor (UINT64 x
544 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
550 int exp
; // unbiased exponent
551 // Note: C1 represents x_significand (UINT64)
553 unsigned int x_nr_bits
;
557 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
561 // check for NaN or Infinity
562 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
564 *pfpsf
|= INVALID_EXCEPTION
;
565 // return Integer Indefinite
566 res
= 0x8000000000000000ull
;
570 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
571 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
572 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
573 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
574 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
575 if (C1
> 9999999999999999ull) { // non-canonical
580 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
581 C1
= x
& MASK_BINARY_SIG1
;
584 // check for zeros (possibly from non-canonical values)
587 res
= 0x0000000000000000ull
;
590 // x is not special and is not zero
592 // q = nr. of decimal digits in x (1 <= q <= 54)
593 // determine first the nr. of bits in x
594 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
595 // split the 64-bit value in two 32-bit halves to avoid rounding errors
596 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
597 tmp1
.d
= (double) (C1
>> 32); // exact conversion
599 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
601 tmp1
.d
= (double) C1
; // exact conversion
603 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
605 } else { // if x < 2^53
606 tmp1
.d
= (double) C1
; // exact conversion
608 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
610 q
= nr_digits
[x_nr_bits
- 1].digits
;
612 q
= nr_digits
[x_nr_bits
- 1].digits1
;
613 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
616 exp
= x_exp
- 398; // unbiased exponent
618 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
620 *pfpsf
|= INVALID_EXCEPTION
;
621 // return Integer Indefinite
622 res
= 0x8000000000000000ull
;
624 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
625 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
626 // so x rounded to an integer may or may not fit in a signed 64-bit int
627 // the cases that do not fit are identified here; the ones that fit
628 // fall through and will be handled with other cases further,
629 // under '1 <= q + exp <= 19'
630 if (x_sign
) { // if n < 0 and q + exp = 19
631 // if n < -2^63 then n is too large
632 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
633 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
634 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
635 // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
636 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
637 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
638 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
639 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] != 0)) {
641 *pfpsf
|= INVALID_EXCEPTION
;
642 // return Integer Indefinite
643 res
= 0x8000000000000000ull
;
646 // else cases that can be rounded to a 64-bit int fall through
647 // to '1 <= q + exp <= 19'
648 } else { // if n > 0 and q + exp = 19
649 // if n >= 2^63 then n is too large
650 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
651 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
652 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
653 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
654 C
.w
[1] = 0x0000000000000005ull
;
655 C
.w
[0] = 0x0000000000000000ull
;
656 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
657 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
658 if (C
.w
[1] >= 0x05ull
) {
659 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
661 *pfpsf
|= INVALID_EXCEPTION
;
662 // return Integer Indefinite
663 res
= 0x8000000000000000ull
;
666 // else cases that can be rounded to a 64-bit int fall through
667 // to '1 <= q + exp <= 19'
668 } // end else if n > 0 and q + exp = 19
669 } // end else if ((q + exp) == 19)
671 // n is not too large to be converted to int64: -2^63 <= n < 2^63
672 // Note: some of the cases tested for above fall through to this point
673 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
676 res
= 0xffffffffffffffffull
;
678 res
= 0x0000000000000000ull
;
680 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
681 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
682 // to nearest to a 64-bit signed integer
683 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
684 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
685 // chop off ind digits from the lower part of C1
686 // C1 fits in 64 bits
687 // calculate C* and f*
688 // C* is actually floor(C*) in this case
689 // C* and f* need shifting and masking, as shown by
690 // shiftright128[] and maskhigh128[]
692 // kx = 10^(-x) = ten2mk64[ind - 1]
694 // the approximation of 10^(-x) was rounded up to 54 bits
695 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
697 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
698 fstar
.w
[0] = P128
.w
[0];
699 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
700 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
701 // C* = floor(C*) (logical right shift; C has p decimal digits,
702 // correct by Property 1)
705 // shift right C* by Ex-64 = shiftright128[ind]
706 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
707 Cstar
= Cstar
>> shift
;
708 // determine inexactness of the rounding of C*
709 // if (0 < f* < 10^(-x)) then
710 // the result is exact
711 // else // if (f* > T*) then
712 // the result is inexact
713 if (ind
- 1 <= 2) { // fstar.w[1] is 0
714 if (fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
715 // ten2mk128trunc[ind -1].w[1] is identical to
716 // ten2mk128[ind -1].w[1]
717 if (x_sign
) { // negative and inexact
720 } // else the result is exact
721 } else { // if 3 <= ind - 1 <= 14
722 if (fstar
.w
[1] || fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
723 // ten2mk128trunc[ind -1].w[1] is identical to
724 // ten2mk128[ind -1].w[1]
725 if (x_sign
) { // negative and inexact
728 } // else the result is exact
735 } else if (exp
== 0) {
737 // res = +/-C (exact)
742 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
743 // (the upper limit of 20 on q + exp is due to the fact that
744 // +/-C * 10^exp is guaranteed to fit in 64 bits)
745 // res = +/-C * 10^exp (exact)
747 res
= -C1
* ten2k64
[exp
];
749 res
= C1
* ten2k64
[exp
];
755 /*****************************************************************************
756 * BID64_to_int64_xfloor
757 ****************************************************************************/
759 #if DECIMAL_CALL_BY_REFERENCE
761 bid64_to_int64_xfloor (SINT64
* pres
, UINT64
* px
762 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
767 bid64_to_int64_xfloor (UINT64 x
768 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
774 int exp
; // unbiased exponent
775 // Note: C1 represents x_significand (UINT64)
777 unsigned int x_nr_bits
;
781 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
785 // check for NaN or Infinity
786 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
788 *pfpsf
|= INVALID_EXCEPTION
;
789 // return Integer Indefinite
790 res
= 0x8000000000000000ull
;
794 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
795 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
796 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
797 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
798 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
799 if (C1
> 9999999999999999ull) { // non-canonical
804 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
805 C1
= x
& MASK_BINARY_SIG1
;
808 // check for zeros (possibly from non-canonical values)
811 res
= 0x0000000000000000ull
;
814 // x is not special and is not zero
816 // q = nr. of decimal digits in x (1 <= q <= 54)
817 // determine first the nr. of bits in x
818 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
819 // split the 64-bit value in two 32-bit halves to avoid rounding errors
820 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
821 tmp1
.d
= (double) (C1
>> 32); // exact conversion
823 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
825 tmp1
.d
= (double) C1
; // exact conversion
827 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
829 } else { // if x < 2^53
830 tmp1
.d
= (double) C1
; // exact conversion
832 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
834 q
= nr_digits
[x_nr_bits
- 1].digits
;
836 q
= nr_digits
[x_nr_bits
- 1].digits1
;
837 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
840 exp
= x_exp
- 398; // unbiased exponent
842 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
844 *pfpsf
|= INVALID_EXCEPTION
;
845 // return Integer Indefinite
846 res
= 0x8000000000000000ull
;
848 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
849 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
850 // so x rounded to an integer may or may not fit in a signed 64-bit int
851 // the cases that do not fit are identified here; the ones that fit
852 // fall through and will be handled with other cases further,
853 // under '1 <= q + exp <= 19'
854 if (x_sign
) { // if n < 0 and q + exp = 19
855 // if n < -2^63 then n is too large
856 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
857 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
858 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
859 // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
860 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
861 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
862 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
863 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] != 0)) {
865 *pfpsf
|= INVALID_EXCEPTION
;
866 // return Integer Indefinite
867 res
= 0x8000000000000000ull
;
870 // else cases that can be rounded to a 64-bit int fall through
871 // to '1 <= q + exp <= 19'
872 } else { // if n > 0 and q + exp = 19
873 // if n >= 2^63 then n is too large
874 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
875 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
876 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
877 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
878 C
.w
[1] = 0x0000000000000005ull
;
879 C
.w
[0] = 0x0000000000000000ull
;
880 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
881 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
882 if (C
.w
[1] >= 0x05ull
) {
883 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
885 *pfpsf
|= INVALID_EXCEPTION
;
886 // return Integer Indefinite
887 res
= 0x8000000000000000ull
;
890 // else cases that can be rounded to a 64-bit int fall through
891 // to '1 <= q + exp <= 19'
892 } // end else if n > 0 and q + exp = 19
893 } // end else if ((q + exp) == 19)
895 // n is not too large to be converted to int64: -2^63 <= n < 2^63
896 // Note: some of the cases tested for above fall through to this point
897 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
899 *pfpsf
|= INEXACT_EXCEPTION
;
902 res
= 0xffffffffffffffffull
;
904 res
= 0x0000000000000000ull
;
906 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
907 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
908 // to nearest to a 64-bit signed integer
909 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
910 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
911 // chop off ind digits from the lower part of C1
912 // C1 fits in 64 bits
913 // calculate C* and f*
914 // C* is actually floor(C*) in this case
915 // C* and f* need shifting and masking, as shown by
916 // shiftright128[] and maskhigh128[]
918 // kx = 10^(-x) = ten2mk64[ind - 1]
920 // the approximation of 10^(-x) was rounded up to 54 bits
921 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
923 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
924 fstar
.w
[0] = P128
.w
[0];
925 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
926 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
927 // C* = floor(C*) (logical right shift; C has p decimal digits,
928 // correct by Property 1)
931 // shift right C* by Ex-64 = shiftright128[ind]
932 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
933 Cstar
= Cstar
>> shift
;
934 // determine inexactness of the rounding of C*
935 // if (0 < f* < 10^(-x)) then
936 // the result is exact
937 // else // if (f* > T*) then
938 // the result is inexact
939 if (ind
- 1 <= 2) { // fstar.w[1] is 0
940 if (fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
941 // ten2mk128trunc[ind -1].w[1] is identical to
942 // ten2mk128[ind -1].w[1]
943 if (x_sign
) { // negative and inexact
946 // set the inexact flag
947 *pfpsf
|= INEXACT_EXCEPTION
;
948 } // else the result is exact
949 } else { // if 3 <= ind - 1 <= 14
950 if (fstar
.w
[1] || fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
951 // ten2mk128trunc[ind -1].w[1] is identical to
952 // ten2mk128[ind -1].w[1]
953 if (x_sign
) { // negative and inexact
956 // set the inexact flag
957 *pfpsf
|= INEXACT_EXCEPTION
;
958 } // else the result is exact
965 } else if (exp
== 0) {
967 // res = +/-C (exact)
972 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
973 // (the upper limit of 20 on q + exp is due to the fact that
974 // +/-C * 10^exp is guaranteed to fit in 64 bits)
975 // res = +/-C * 10^exp (exact)
977 res
= -C1
* ten2k64
[exp
];
979 res
= C1
* ten2k64
[exp
];
985 /*****************************************************************************
986 * BID64_to_int64_ceil
987 ****************************************************************************/
989 #if DECIMAL_CALL_BY_REFERENCE
991 bid64_to_int64_ceil (SINT64
* pres
, UINT64
* px
992 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
)
997 bid64_to_int64_ceil (UINT64 x
998 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
)
1004 int exp
; // unbiased exponent
1005 // Note: C1 represents x_significand (UINT64)
1006 BID_UI64DOUBLE tmp1
;
1007 unsigned int x_nr_bits
;
1011 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
1015 // check for NaN or Infinity
1016 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
1018 *pfpsf
|= INVALID_EXCEPTION
;
1019 // return Integer Indefinite
1020 res
= 0x8000000000000000ull
;
1024 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1025 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1026 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1027 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
1028 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1029 if (C1
> 9999999999999999ull) { // non-canonical
1034 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
1035 C1
= x
& MASK_BINARY_SIG1
;
1038 // check for zeros (possibly from non-canonical values)
1044 // x is not special and is not zero
1046 // q = nr. of decimal digits in x (1 <= q <= 54)
1047 // determine first the nr. of bits in x
1048 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1049 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1050 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
1051 tmp1
.d
= (double) (C1
>> 32); // exact conversion
1053 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1054 } else { // x < 2^32
1055 tmp1
.d
= (double) C1
; // exact conversion
1057 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1059 } else { // if x < 2^53
1060 tmp1
.d
= (double) C1
; // exact conversion
1062 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1064 q
= nr_digits
[x_nr_bits
- 1].digits
;
1066 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1067 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
1070 exp
= x_exp
- 398; // unbiased exponent
1072 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1074 *pfpsf
|= INVALID_EXCEPTION
;
1075 // return Integer Indefinite
1076 res
= 0x8000000000000000ull
;
1078 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1079 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1080 // so x rounded to an integer may or may not fit in a signed 64-bit int
1081 // the cases that do not fit are identified here; the ones that fit
1082 // fall through and will be handled with other cases further,
1083 // under '1 <= q + exp <= 19'
1084 if (x_sign
) { // if n < 0 and q + exp = 19
1085 // if n <= -2^63 - 1 then n is too large
1086 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1087 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1088 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1089 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1090 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1091 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1092 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1093 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x0aull
)) {
1095 *pfpsf
|= INVALID_EXCEPTION
;
1096 // return Integer Indefinite
1097 res
= 0x8000000000000000ull
;
1100 // else cases that can be rounded to a 64-bit int fall through
1101 // to '1 <= q + exp <= 19'
1102 } else { // if n > 0 and q + exp = 19
1103 // if n > 2^63 - 1 then n is too large
1104 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1105 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
1106 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
1107 // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
1108 C
.w
[1] = 0x0000000000000004ull
;
1109 C
.w
[0] = 0xfffffffffffffff6ull
;
1110 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1111 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1112 if (C
.w
[1] > 0x04ull
||
1113 (C
.w
[1] == 0x04ull
&& C
.w
[0] > 0xfffffffffffffff6ull
)) {
1115 *pfpsf
|= INVALID_EXCEPTION
;
1116 // return Integer Indefinite
1117 res
= 0x8000000000000000ull
;
1120 // else cases that can be rounded to a 64-bit int fall through
1121 // to '1 <= q + exp <= 19'
1122 } // end else if n > 0 and q + exp = 19
1123 } // end else if ((q + exp) == 19)
1125 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1126 // Note: some of the cases tested for above fall through to this point
1127 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1134 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1135 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1136 // to nearest to a 64-bit signed integer
1137 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1138 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
1139 // chop off ind digits from the lower part of C1
1140 // C1 fits in 64 bits
1141 // calculate C* and f*
1142 // C* is actually floor(C*) in this case
1143 // C* and f* need shifting and masking, as shown by
1144 // shiftright128[] and maskhigh128[]
1146 // kx = 10^(-x) = ten2mk64[ind - 1]
1147 // C* = C1 * 10^(-x)
1148 // the approximation of 10^(-x) was rounded up to 54 bits
1149 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
1151 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
1152 fstar
.w
[0] = P128
.w
[0];
1153 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
1154 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
1155 // C* = floor(C*) (logical right shift; C has p decimal digits,
1156 // correct by Property 1)
1157 // n = C* * 10^(e+x)
1159 // shift right C* by Ex-64 = shiftright128[ind]
1160 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
1161 Cstar
= Cstar
>> shift
;
1162 // determine inexactness of the rounding of C*
1163 // if (0 < f* < 10^(-x)) then
1164 // the result is exact
1165 // else // if (f* > T*) then
1166 // the result is inexact
1167 if (ind
- 1 <= 2) { // fstar.w[1] is 0
1168 if (fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1169 // ten2mk128trunc[ind -1].w[1] is identical to
1170 // ten2mk128[ind -1].w[1]
1171 if (!x_sign
) { // positive and inexact
1174 } // else the result is exact
1175 } else { // if 3 <= ind - 1 <= 14
1176 if (fstar
.w
[1] || fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1177 // ten2mk128trunc[ind -1].w[1] is identical to
1178 // ten2mk128[ind -1].w[1]
1179 if (!x_sign
) { // positive and inexact
1182 } // else the result is exact
1189 } else if (exp
== 0) {
1191 // res = +/-C (exact)
1196 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1197 // (the upper limit of 20 on q + exp is due to the fact that
1198 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1199 // res = +/-C * 10^exp (exact)
1201 res
= -C1
* ten2k64
[exp
];
1203 res
= C1
* ten2k64
[exp
];
1209 /*****************************************************************************
1210 * BID64_to_int64_xceil
1211 ****************************************************************************/
1213 #if DECIMAL_CALL_BY_REFERENCE
1215 bid64_to_int64_xceil (SINT64
* pres
, UINT64
* px
1216 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1221 bid64_to_int64_xceil (UINT64 x
1222 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1228 int exp
; // unbiased exponent
1229 // Note: C1 represents x_significand (UINT64)
1230 BID_UI64DOUBLE tmp1
;
1231 unsigned int x_nr_bits
;
1235 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
1239 // check for NaN or Infinity
1240 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
1242 *pfpsf
|= INVALID_EXCEPTION
;
1243 // return Integer Indefinite
1244 res
= 0x8000000000000000ull
;
1248 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1249 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1250 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1251 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
1252 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1253 if (C1
> 9999999999999999ull) { // non-canonical
1258 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
1259 C1
= x
& MASK_BINARY_SIG1
;
1262 // check for zeros (possibly from non-canonical values)
1268 // x is not special and is not zero
1270 // q = nr. of decimal digits in x (1 <= q <= 54)
1271 // determine first the nr. of bits in x
1272 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1273 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1274 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
1275 tmp1
.d
= (double) (C1
>> 32); // exact conversion
1277 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1278 } else { // x < 2^32
1279 tmp1
.d
= (double) C1
; // exact conversion
1281 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1283 } else { // if x < 2^53
1284 tmp1
.d
= (double) C1
; // exact conversion
1286 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1288 q
= nr_digits
[x_nr_bits
- 1].digits
;
1290 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1291 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
1294 exp
= x_exp
- 398; // unbiased exponent
1296 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1298 *pfpsf
|= INVALID_EXCEPTION
;
1299 // return Integer Indefinite
1300 res
= 0x8000000000000000ull
;
1302 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1303 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1304 // so x rounded to an integer may or may not fit in a signed 64-bit int
1305 // the cases that do not fit are identified here; the ones that fit
1306 // fall through and will be handled with other cases further,
1307 // under '1 <= q + exp <= 19'
1308 if (x_sign
) { // if n < 0 and q + exp = 19
1309 // if n <= -2^63 - 1 then n is too large
1310 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1311 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1312 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1313 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1314 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1315 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1316 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1317 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x0aull
)) {
1319 *pfpsf
|= INVALID_EXCEPTION
;
1320 // return Integer Indefinite
1321 res
= 0x8000000000000000ull
;
1324 // else cases that can be rounded to a 64-bit int fall through
1325 // to '1 <= q + exp <= 19'
1326 } else { // if n > 0 and q + exp = 19
1327 // if n > 2^63 - 1 then n is too large
1328 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1329 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
1330 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
1331 // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
1332 C
.w
[1] = 0x0000000000000004ull
;
1333 C
.w
[0] = 0xfffffffffffffff6ull
;
1334 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1335 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1336 if (C
.w
[1] > 0x04ull
||
1337 (C
.w
[1] == 0x04ull
&& C
.w
[0] > 0xfffffffffffffff6ull
)) {
1339 *pfpsf
|= INVALID_EXCEPTION
;
1340 // return Integer Indefinite
1341 res
= 0x8000000000000000ull
;
1344 // else cases that can be rounded to a 64-bit int fall through
1345 // to '1 <= q + exp <= 19'
1346 } // end else if n > 0 and q + exp = 19
1347 } // end else if ((q + exp) == 19)
1349 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1350 // Note: some of the cases tested for above fall through to this point
1351 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1353 *pfpsf
|= INEXACT_EXCEPTION
;
1360 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1361 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1362 // to nearest to a 64-bit signed integer
1363 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1364 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
1365 // chop off ind digits from the lower part of C1
1366 // C1 fits in 64 bits
1367 // calculate C* and f*
1368 // C* is actually floor(C*) in this case
1369 // C* and f* need shifting and masking, as shown by
1370 // shiftright128[] and maskhigh128[]
1372 // kx = 10^(-x) = ten2mk64[ind - 1]
1373 // C* = C1 * 10^(-x)
1374 // the approximation of 10^(-x) was rounded up to 54 bits
1375 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
1377 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
1378 fstar
.w
[0] = P128
.w
[0];
1379 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
1380 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
1381 // C* = floor(C*) (logical right shift; C has p decimal digits,
1382 // correct by Property 1)
1383 // n = C* * 10^(e+x)
1385 // shift right C* by Ex-64 = shiftright128[ind]
1386 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
1387 Cstar
= Cstar
>> shift
;
1388 // determine inexactness of the rounding of C*
1389 // if (0 < f* < 10^(-x)) then
1390 // the result is exact
1391 // else // if (f* > T*) then
1392 // the result is inexact
1393 if (ind
- 1 <= 2) { // fstar.w[1] is 0
1394 if (fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1395 // ten2mk128trunc[ind -1].w[1] is identical to
1396 // ten2mk128[ind -1].w[1]
1397 if (!x_sign
) { // positive and inexact
1400 // set the inexact flag
1401 *pfpsf
|= INEXACT_EXCEPTION
;
1402 } // else the result is exact
1403 } else { // if 3 <= ind - 1 <= 14
1404 if (fstar
.w
[1] || fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1405 // ten2mk128trunc[ind -1].w[1] is identical to
1406 // ten2mk128[ind -1].w[1]
1407 if (!x_sign
) { // positive and inexact
1410 // set the inexact flag
1411 *pfpsf
|= INEXACT_EXCEPTION
;
1412 } // else the result is exact
1419 } else if (exp
== 0) {
1421 // res = +/-C (exact)
1426 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1427 // (the upper limit of 20 on q + exp is due to the fact that
1428 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1429 // res = +/-C * 10^exp (exact)
1431 res
= -C1
* ten2k64
[exp
];
1433 res
= C1
* ten2k64
[exp
];
1439 /*****************************************************************************
1440 * BID64_to_int64_int
1441 ****************************************************************************/
1443 #if DECIMAL_CALL_BY_REFERENCE
1445 bid64_to_int64_int (SINT64
* pres
, UINT64
* px
1446 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
1450 bid64_to_int64_int (UINT64 x
1451 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
1456 int exp
; // unbiased exponent
1457 // Note: C1 represents x_significand (UINT64)
1458 BID_UI64DOUBLE tmp1
;
1459 unsigned int x_nr_bits
;
1463 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
1466 // check for NaN or Infinity
1467 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
1469 *pfpsf
|= INVALID_EXCEPTION
;
1470 // return Integer Indefinite
1471 res
= 0x8000000000000000ull
;
1475 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1476 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1477 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1478 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
1479 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1480 if (C1
> 9999999999999999ull) { // non-canonical
1485 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
1486 C1
= x
& MASK_BINARY_SIG1
;
1489 // check for zeros (possibly from non-canonical values)
1495 // x is not special and is not zero
1497 // q = nr. of decimal digits in x (1 <= q <= 54)
1498 // determine first the nr. of bits in x
1499 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1500 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1501 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
1502 tmp1
.d
= (double) (C1
>> 32); // exact conversion
1504 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1505 } else { // x < 2^32
1506 tmp1
.d
= (double) C1
; // exact conversion
1508 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1510 } else { // if x < 2^53
1511 tmp1
.d
= (double) C1
; // exact conversion
1513 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1515 q
= nr_digits
[x_nr_bits
- 1].digits
;
1517 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1518 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
1521 exp
= x_exp
- 398; // unbiased exponent
1523 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1525 *pfpsf
|= INVALID_EXCEPTION
;
1526 // return Integer Indefinite
1527 res
= 0x8000000000000000ull
;
1529 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1530 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1531 // so x rounded to an integer may or may not fit in a signed 64-bit int
1532 // the cases that do not fit are identified here; the ones that fit
1533 // fall through and will be handled with other cases further,
1534 // under '1 <= q + exp <= 19'
1535 if (x_sign
) { // if n < 0 and q + exp = 19
1536 // if n <= -2^63 - 1 then n is too large
1537 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1538 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1539 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1540 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1541 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1542 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1543 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1544 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x0aull
)) {
1546 *pfpsf
|= INVALID_EXCEPTION
;
1547 // return Integer Indefinite
1548 res
= 0x8000000000000000ull
;
1551 // else cases that can be rounded to a 64-bit int fall through
1552 // to '1 <= q + exp <= 19'
1553 } else { // if n > 0 and q + exp = 19
1554 // if n >= 2^63 then n is too large
1555 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1556 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
1557 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
1558 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
1559 C
.w
[1] = 0x0000000000000005ull
;
1560 C
.w
[0] = 0x0000000000000000ull
;
1561 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1562 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1563 if (C
.w
[1] >= 0x05ull
) {
1564 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1566 *pfpsf
|= INVALID_EXCEPTION
;
1567 // return Integer Indefinite
1568 res
= 0x8000000000000000ull
;
1571 // else cases that can be rounded to a 64-bit int fall through
1572 // to '1 <= q + exp <= 19'
1573 } // end else if n > 0 and q + exp = 19
1574 } // end else if ((q + exp) == 19)
1576 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1577 // Note: some of the cases tested for above fall through to this point
1578 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1580 res
= 0x0000000000000000ull
;
1582 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1583 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1584 // to nearest to a 64-bit signed integer
1585 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1586 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
1587 // chop off ind digits from the lower part of C1
1588 // C1 fits in 64 bits
1589 // calculate C* and f*
1590 // C* is actually floor(C*) in this case
1591 // C* and f* need shifting and masking, as shown by
1592 // shiftright128[] and maskhigh128[]
1594 // kx = 10^(-x) = ten2mk64[ind - 1]
1595 // C* = C1 * 10^(-x)
1596 // the approximation of 10^(-x) was rounded up to 54 bits
1597 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
1599 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
1600 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
1601 // C* = floor(C*) (logical right shift; C has p decimal digits,
1602 // correct by Property 1)
1603 // n = C* * 10^(e+x)
1605 // shift right C* by Ex-64 = shiftright128[ind]
1606 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
1607 Cstar
= Cstar
>> shift
;
1613 } else if (exp
== 0) {
1615 // res = +/-C (exact)
1620 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1621 // (the upper limit of 20 on q + exp is due to the fact that
1622 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1623 // res = +/-C * 10^exp (exact)
1625 res
= -C1
* ten2k64
[exp
];
1627 res
= C1
* ten2k64
[exp
];
1633 /*****************************************************************************
1634 * BID64_to_int64_xint
1635 ****************************************************************************/
1637 #if DECIMAL_CALL_BY_REFERENCE
1639 bid64_to_int64_xint (SINT64
* pres
, UINT64
* px
1640 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
)
1645 bid64_to_int64_xint (UINT64 x
1646 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
)
1652 int exp
; // unbiased exponent
1653 // Note: C1 represents x_significand (UINT64)
1654 BID_UI64DOUBLE tmp1
;
1655 unsigned int x_nr_bits
;
1659 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
1663 // check for NaN or Infinity
1664 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
1666 *pfpsf
|= INVALID_EXCEPTION
;
1667 // return Integer Indefinite
1668 res
= 0x8000000000000000ull
;
1672 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1673 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1674 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1675 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
1676 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1677 if (C1
> 9999999999999999ull) { // non-canonical
1682 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
1683 C1
= x
& MASK_BINARY_SIG1
;
1686 // check for zeros (possibly from non-canonical values)
1692 // x is not special and is not zero
1694 // q = nr. of decimal digits in x (1 <= q <= 54)
1695 // determine first the nr. of bits in x
1696 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1697 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1698 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
1699 tmp1
.d
= (double) (C1
>> 32); // exact conversion
1701 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1702 } else { // x < 2^32
1703 tmp1
.d
= (double) C1
; // exact conversion
1705 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1707 } else { // if x < 2^53
1708 tmp1
.d
= (double) C1
; // exact conversion
1710 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1712 q
= nr_digits
[x_nr_bits
- 1].digits
;
1714 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1715 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
1718 exp
= x_exp
- 398; // unbiased exponent
1720 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1722 *pfpsf
|= INVALID_EXCEPTION
;
1723 // return Integer Indefinite
1724 res
= 0x8000000000000000ull
;
1726 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1727 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1728 // so x rounded to an integer may or may not fit in a signed 64-bit int
1729 // the cases that do not fit are identified here; the ones that fit
1730 // fall through and will be handled with other cases further,
1731 // under '1 <= q + exp <= 19'
1732 if (x_sign
) { // if n < 0 and q + exp = 19
1733 // if n <= -2^63 - 1 then n is too large
1734 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1735 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1736 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1737 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1738 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1739 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1740 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1741 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x0aull
)) {
1743 *pfpsf
|= INVALID_EXCEPTION
;
1744 // return Integer Indefinite
1745 res
= 0x8000000000000000ull
;
1748 // else cases that can be rounded to a 64-bit int fall through
1749 // to '1 <= q + exp <= 19'
1750 } else { // if n > 0 and q + exp = 19
1751 // if n >= 2^63 then n is too large
1752 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1753 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
1754 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
1755 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
1756 C
.w
[1] = 0x0000000000000005ull
;
1757 C
.w
[0] = 0x0000000000000000ull
;
1758 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1759 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1760 if (C
.w
[1] >= 0x05ull
) {
1761 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1763 *pfpsf
|= INVALID_EXCEPTION
;
1764 // return Integer Indefinite
1765 res
= 0x8000000000000000ull
;
1768 // else cases that can be rounded to a 64-bit int fall through
1769 // to '1 <= q + exp <= 19'
1770 } // end else if n > 0 and q + exp = 19
1771 } // end else if ((q + exp) == 19)
1773 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1774 // Note: some of the cases tested for above fall through to this point
1775 if ((q
+ exp
) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1777 *pfpsf
|= INEXACT_EXCEPTION
;
1779 res
= 0x0000000000000000ull
;
1781 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1782 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1783 // to nearest to a 64-bit signed integer
1784 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1785 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
1786 // chop off ind digits from the lower part of C1
1787 // C1 fits in 64 bits
1788 // calculate C* and f*
1789 // C* is actually floor(C*) in this case
1790 // C* and f* need shifting and masking, as shown by
1791 // shiftright128[] and maskhigh128[]
1793 // kx = 10^(-x) = ten2mk64[ind - 1]
1794 // C* = C1 * 10^(-x)
1795 // the approximation of 10^(-x) was rounded up to 54 bits
1796 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
1798 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
1799 fstar
.w
[0] = P128
.w
[0];
1800 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
1801 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
1802 // C* = floor(C*) (logical right shift; C has p decimal digits,
1803 // correct by Property 1)
1804 // n = C* * 10^(e+x)
1806 // shift right C* by Ex-64 = shiftright128[ind]
1807 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
1808 Cstar
= Cstar
>> shift
;
1809 // determine inexactness of the rounding of C*
1810 // if (0 < f* < 10^(-x)) then
1811 // the result is exact
1812 // else // if (f* > T*) then
1813 // the result is inexact
1814 if (ind
- 1 <= 2) { // fstar.w[1] is 0
1815 if (fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1816 // ten2mk128trunc[ind -1].w[1] is identical to
1817 // ten2mk128[ind -1].w[1]
1818 // set the inexact flag
1819 *pfpsf
|= INEXACT_EXCEPTION
;
1820 } // else the result is exact
1821 } else { // if 3 <= ind - 1 <= 14
1822 if (fstar
.w
[1] || fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
1823 // ten2mk128trunc[ind -1].w[1] is identical to
1824 // ten2mk128[ind -1].w[1]
1825 // set the inexact flag
1826 *pfpsf
|= INEXACT_EXCEPTION
;
1827 } // else the result is exact
1833 } else if (exp
== 0) {
1835 // res = +/-C (exact)
1840 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1841 // (the upper limit of 20 on q + exp is due to the fact that
1842 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1843 // res = +/-C * 10^exp (exact)
1845 res
= -C1
* ten2k64
[exp
];
1847 res
= C1
* ten2k64
[exp
];
1853 /*****************************************************************************
1854 * BID64_to_int64_rninta
1855 ****************************************************************************/
1857 #if DECIMAL_CALL_BY_REFERENCE
1859 bid64_to_int64_rninta (SINT64
* pres
, UINT64
* px
1860 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1865 bid64_to_int64_rninta (UINT64 x
1866 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1872 int exp
; // unbiased exponent
1873 // Note: C1 represents x_significand (UINT64)
1874 BID_UI64DOUBLE tmp1
;
1875 unsigned int x_nr_bits
;
1879 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
1882 // check for NaN or Infinity
1883 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
1885 *pfpsf
|= INVALID_EXCEPTION
;
1886 // return Integer Indefinite
1887 res
= 0x8000000000000000ull
;
1891 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1892 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1893 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1894 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
1895 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1896 if (C1
> 9999999999999999ull) { // non-canonical
1901 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
1902 C1
= x
& MASK_BINARY_SIG1
;
1905 // check for zeros (possibly from non-canonical values)
1911 // x is not special and is not zero
1913 // q = nr. of decimal digits in x (1 <= q <= 54)
1914 // determine first the nr. of bits in x
1915 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1916 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1917 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
1918 tmp1
.d
= (double) (C1
>> 32); // exact conversion
1920 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1921 } else { // x < 2^32
1922 tmp1
.d
= (double) C1
; // exact conversion
1924 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1926 } else { // if x < 2^53
1927 tmp1
.d
= (double) C1
; // exact conversion
1929 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1931 q
= nr_digits
[x_nr_bits
- 1].digits
;
1933 q
= nr_digits
[x_nr_bits
- 1].digits1
;
1934 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
1937 exp
= x_exp
- 398; // unbiased exponent
1939 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1941 *pfpsf
|= INVALID_EXCEPTION
;
1942 // return Integer Indefinite
1943 res
= 0x8000000000000000ull
;
1945 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1946 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1947 // so x rounded to an integer may or may not fit in a signed 64-bit int
1948 // the cases that do not fit are identified here; the ones that fit
1949 // fall through and will be handled with other cases further,
1950 // under '1 <= q + exp <= 19'
1951 if (x_sign
) { // if n < 0 and q + exp = 19
1952 // if n <= -2^63 - 1/2 then n is too large
1953 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
1954 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
1955 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
1956 // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
1957 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1958 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1959 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
1960 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x05ull
)) {
1962 *pfpsf
|= INVALID_EXCEPTION
;
1963 // return Integer Indefinite
1964 res
= 0x8000000000000000ull
;
1967 // else cases that can be rounded to a 64-bit int fall through
1968 // to '1 <= q + exp <= 19'
1969 } else { // if n > 0 and q + exp = 19
1970 // if n >= 2^63 - 1/2 then n is too large
1971 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
1972 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
1973 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
1974 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
1975 C
.w
[1] = 0x0000000000000004ull
;
1976 C
.w
[0] = 0xfffffffffffffffbull
;
1977 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1978 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
1979 if (C
.w
[1] > 0x04ull
||
1980 (C
.w
[1] == 0x04ull
&& C
.w
[0] >= 0xfffffffffffffffbull
)) {
1982 *pfpsf
|= INVALID_EXCEPTION
;
1983 // return Integer Indefinite
1984 res
= 0x8000000000000000ull
;
1987 // else cases that can be rounded to a 64-bit int fall through
1988 // to '1 <= q + exp <= 19'
1989 } // end else if n > 0 and q + exp = 19
1990 } // end else if ((q + exp) == 19)
1992 // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
1993 // Note: some of the cases tested for above fall through to this point
1994 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1996 res
= 0x0000000000000000ull
;
1998 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
1999 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
2003 ind
= q
- 1; // 0 <= ind <= 15
2004 if (C1
< midpoint64
[ind
]) {
2005 res
= 0x0000000000000000ull
; // return 0
2006 } else if (x_sign
) { // n < 0
2007 res
= 0xffffffffffffffffull
; // return -1
2009 res
= 0x0000000000000001ull
; // return +1
2011 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
2012 // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2013 // to nearest to a 64-bit signed integer
2014 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
2015 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
2016 // chop off ind digits from the lower part of C1
2017 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
2018 C1
= C1
+ midpoint64
[ind
- 1];
2019 // calculate C* and f*
2020 // C* is actually floor(C*) in this case
2021 // C* and f* need shifting and masking, as shown by
2022 // shiftright128[] and maskhigh128[]
2024 // kx = 10^(-x) = ten2mk64[ind - 1]
2025 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2026 // the approximation of 10^(-x) was rounded up to 54 bits
2027 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
2029 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
2030 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
2031 // if (0 < f* < 10^(-x)) then the result is a midpoint
2032 // if floor(C*) is even then C* = floor(C*) - logical right
2033 // shift; C* has p decimal digits, correct by Prop. 1)
2034 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2035 // shift; C* has p decimal digits, correct by Pr. 1)
2037 // C* = floor(C*) (logical right shift; C has p decimal digits,
2038 // correct by Property 1)
2039 // n = C* * 10^(e+x)
2041 // shift right C* by Ex-64 = shiftright128[ind]
2042 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
2043 Cstar
= Cstar
>> shift
;
2045 // if the result was a midpoint it was rounded away from zero
2050 } else if (exp
== 0) {
2052 // res = +/-C (exact)
2057 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
2058 // (the upper limit of 20 on q + exp is due to the fact that
2059 // +/-C * 10^exp is guaranteed to fit in 64 bits)
2060 // res = +/-C * 10^exp (exact)
2062 res
= -C1
* ten2k64
[exp
];
2064 res
= C1
* ten2k64
[exp
];
2070 /*****************************************************************************
2071 * BID64_to_int64_xrninta
2072 ****************************************************************************/
2074 #if DECIMAL_CALL_BY_REFERENCE
2076 bid64_to_int64_xrninta (SINT64
* pres
, UINT64
* px
2077 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2082 bid64_to_int64_xrninta (UINT64 x
2083 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2089 int exp
; // unbiased exponent
2090 // Note: C1 represents x_significand (UINT64)
2092 BID_UI64DOUBLE tmp1
;
2093 unsigned int x_nr_bits
;
2097 UINT64 Cstar
; // C* represents up to 16 decimal digits ~ 54 bits
2101 // check for NaN or Infinity
2102 if ((x
& MASK_NAN
) == MASK_NAN
|| (x
& MASK_INF
) == MASK_INF
) {
2104 *pfpsf
|= INVALID_EXCEPTION
;
2105 // return Integer Indefinite
2106 res
= 0x8000000000000000ull
;
2110 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
2111 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
2112 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
2113 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
2114 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
2115 if (C1
> 9999999999999999ull) { // non-canonical
2120 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
2121 C1
= x
& MASK_BINARY_SIG1
;
2124 // check for zeros (possibly from non-canonical values)
2130 // x is not special and is not zero
2132 // q = nr. of decimal digits in x (1 <= q <= 54)
2133 // determine first the nr. of bits in x
2134 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
2135 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2136 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
2137 tmp1
.d
= (double) (C1
>> 32); // exact conversion
2139 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2140 } else { // x < 2^32
2141 tmp1
.d
= (double) C1
; // exact conversion
2143 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2145 } else { // if x < 2^53
2146 tmp1
.d
= (double) C1
; // exact conversion
2148 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
2150 q
= nr_digits
[x_nr_bits
- 1].digits
;
2152 q
= nr_digits
[x_nr_bits
- 1].digits1
;
2153 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
2156 exp
= x_exp
- 398; // unbiased exponent
2158 if ((q
+ exp
) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2160 *pfpsf
|= INVALID_EXCEPTION
;
2161 // return Integer Indefinite
2162 res
= 0x8000000000000000ull
;
2164 } else if ((q
+ exp
) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
2165 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2166 // so x rounded to an integer may or may not fit in a signed 64-bit int
2167 // the cases that do not fit are identified here; the ones that fit
2168 // fall through and will be handled with other cases further,
2169 // under '1 <= q + exp <= 19'
2170 if (x_sign
) { // if n < 0 and q + exp = 19
2171 // if n <= -2^63 - 1/2 then n is too large
2172 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
2173 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
2174 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
2175 // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
2176 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2177 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
2178 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
2179 if (C
.w
[1] > 0x05ull
|| (C
.w
[1] == 0x05ull
&& C
.w
[0] >= 0x05ull
)) {
2181 *pfpsf
|= INVALID_EXCEPTION
;
2182 // return Integer Indefinite
2183 res
= 0x8000000000000000ull
;
2186 // else cases that can be rounded to a 64-bit int fall through
2187 // to '1 <= q + exp <= 19'
2188 } else { // if n > 0 and q + exp = 19
2189 // if n >= 2^63 - 1/2 then n is too large
2190 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
2191 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
2192 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
2193 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
2194 C
.w
[1] = 0x0000000000000004ull
;
2195 C
.w
[0] = 0xfffffffffffffffbull
;
2196 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2197 __mul_64x64_to_128MACH (C
, C1
, ten2k64
[20 - q
]);
2198 if (C
.w
[1] > 0x04ull
||
2199 (C
.w
[1] == 0x04ull
&& C
.w
[0] >= 0xfffffffffffffffbull
)) {
2201 *pfpsf
|= INVALID_EXCEPTION
;
2202 // return Integer Indefinite
2203 res
= 0x8000000000000000ull
;
2206 // else cases that can be rounded to a 64-bit int fall through
2207 // to '1 <= q + exp <= 19'
2208 } // end else if n > 0 and q + exp = 19
2209 } // end else if ((q + exp) == 19)
2211 // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
2212 // Note: some of the cases tested for above fall through to this point
2213 if ((q
+ exp
) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2215 *pfpsf
|= INEXACT_EXCEPTION
;
2217 res
= 0x0000000000000000ull
;
2219 } else if ((q
+ exp
) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2220 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
2224 ind
= q
- 1; // 0 <= ind <= 15
2225 if (C1
< midpoint64
[ind
]) {
2226 res
= 0x0000000000000000ull
; // return 0
2227 } else if (x_sign
) { // n < 0
2228 res
= 0xffffffffffffffffull
; // return -1
2230 res
= 0x0000000000000001ull
; // return +1
2233 *pfpsf
|= INEXACT_EXCEPTION
;
2234 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
2235 // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2236 // to nearest to a 64-bit signed integer
2237 if (exp
< 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
2238 ind
= -exp
; // 1 <= ind <= 15; ind is a synonym for 'x'
2239 // chop off ind digits from the lower part of C1
2240 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
2241 C1
= C1
+ midpoint64
[ind
- 1];
2242 // calculate C* and f*
2243 // C* is actually floor(C*) in this case
2244 // C* and f* need shifting and masking, as shown by
2245 // shiftright128[] and maskhigh128[]
2247 // kx = 10^(-x) = ten2mk64[ind - 1]
2248 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2249 // the approximation of 10^(-x) was rounded up to 54 bits
2250 __mul_64x64_to_128MACH (P128
, C1
, ten2mk64
[ind
- 1]);
2252 fstar
.w
[1] = P128
.w
[1] & maskhigh128
[ind
- 1];
2253 fstar
.w
[0] = P128
.w
[0];
2254 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
2255 // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
2256 // if (0 < f* < 10^(-x)) then the result is a midpoint
2257 // if floor(C*) is even then C* = floor(C*) - logical right
2258 // shift; C* has p decimal digits, correct by Prop. 1)
2259 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2260 // shift; C* has p decimal digits, correct by Pr. 1)
2262 // C* = floor(C*) (logical right shift; C has p decimal digits,
2263 // correct by Property 1)
2264 // n = C* * 10^(e+x)
2266 // shift right C* by Ex-64 = shiftright128[ind]
2267 shift
= shiftright128
[ind
- 1]; // 0 <= shift <= 39
2268 Cstar
= Cstar
>> shift
;
2269 // determine inexactness of the rounding of C*
2270 // if (0 < f* - 1/2 < 10^(-x)) then
2271 // the result is exact
2272 // else // if (f* - 1/2 > T*) then
2273 // the result is inexact
2275 if (fstar
.w
[0] > 0x8000000000000000ull
) {
2276 // f* > 1/2 and the result may be exact
2277 tmp64
= fstar
.w
[0] - 0x8000000000000000ull
; // f* - 1/2
2278 if ((tmp64
> ten2mk128trunc
[ind
- 1].w
[1])) {
2279 // ten2mk128trunc[ind -1].w[1] is identical to
2280 // ten2mk128[ind -1].w[1]
2281 // set the inexact flag
2282 *pfpsf
|= INEXACT_EXCEPTION
;
2283 } // else the result is exact
2284 } else { // the result is inexact; f2* <= 1/2
2285 // set the inexact flag
2286 *pfpsf
|= INEXACT_EXCEPTION
;
2288 } else { // if 3 <= ind - 1 <= 14
2289 if (fstar
.w
[1] > onehalf128
[ind
- 1] ||
2290 (fstar
.w
[1] == onehalf128
[ind
- 1] && fstar
.w
[0])) {
2291 // f2* > 1/2 and the result may be exact
2292 // Calculate f2* - 1/2
2293 tmp64
= fstar
.w
[1] - onehalf128
[ind
- 1];
2294 if (tmp64
|| fstar
.w
[0] > ten2mk128trunc
[ind
- 1].w
[1]) {
2295 // ten2mk128trunc[ind -1].w[1] is identical to
2296 // ten2mk128[ind -1].w[1]
2297 // set the inexact flag
2298 *pfpsf
|= INEXACT_EXCEPTION
;
2299 } // else the result is exact
2300 } else { // the result is inexact; f2* <= 1/2
2301 // set the inexact flag
2302 *pfpsf
|= INEXACT_EXCEPTION
;
2306 // if the result was a midpoint it was rounded away from zero
2311 } else if (exp
== 0) {
2313 // res = +/-C (exact)
2318 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
2319 // (the upper limit of 20 on q + exp is due to the fact that
2320 // +/-C * 10^exp is guaranteed to fit in 64 bits)
2321 // res = +/-C * 10^exp (exact)
2323 res
= -C1
* ten2k64
[exp
];
2325 res
= C1
* ten2k64
[exp
];