1 /* Copyright (C) 2007 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 2, or (at your option) any later
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29 #include "bid_internal.h"
31 /*****************************************************************************
32 * BID64_round_integral_exact
33 ****************************************************************************/
35 #if DECIMAL_CALL_BY_REFERENCE
37 __bid64_round_integral_exact (UINT64
* pres
,
39 px _RND_MODE_PARAM _EXC_FLAGS_PARAM
40 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
42 #if !DECIMAL_GLOBAL_ROUNDING
43 unsigned int rnd_mode
= *prnd_mode
;
47 __bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM
48 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
51 UINT64 res
= 0xbaddbaddbaddbaddull
;
53 int exp
; // unbiased exponent
54 // Note: C1 represents the significand (UINT64)
59 // UINT64 res is C* at first - represents up to 16 decimal digits <= 54 bits
60 UINT128 fstar
= {{ 0x0ull
, 0x0ull
}};;
63 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
65 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
67 *pfpsf
|= INVALID_EXCEPTION
;
68 // return Quiet (SNaN)
69 res
= x
& 0xfdffffffffffffffull
;
71 // return original input if QNaN or INF, quietize if SNaN
75 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
76 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
77 // if the steering bits are 11 (condition will be 0), then
78 // the exponent is G[0:w+1]
79 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
80 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
81 if (C1
> 9999999999999999ull) { // non-canonical
85 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
86 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
87 C1
= (x
& MASK_BINARY_SIG1
);
90 // if x is 0 or non-canonical return 0 preserving the sign bit and
91 // the preferred exponent of MAX(Q(x), 0)
95 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
98 // x is a finite non-zero number (not 0, non-canonical, or special)
101 case ROUNDING_TO_NEAREST
:
102 case ROUNDING_TIES_AWAY
:
103 // return 0 if (exp <= -(p+1))
105 res
= x_sign
| 0x31c0000000000000ull
;
106 *pfpsf
|= INEXACT_EXCEPTION
;
111 // return 0 if (exp <= -p)
114 res
= 0xb1c0000000000001ull
;
116 res
= 0x31c0000000000000ull
;
118 *pfpsf
|= INEXACT_EXCEPTION
;
123 // return 0 if (exp <= -p)
126 res
= 0xb1c0000000000000ull
;
128 res
= 0x31c0000000000001ull
;
130 *pfpsf
|= INEXACT_EXCEPTION
;
134 case ROUNDING_TO_ZERO
:
135 // return 0 if (exp <= -p)
137 res
= x_sign
| 0x31c0000000000000ull
;
138 *pfpsf
|= INEXACT_EXCEPTION
;
144 // q = nr. of decimal digits in x (1 <= q <= 54)
145 // determine first the nr. of bits in x
146 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
148 } else { // if x < 2^53
149 tmp1
.d
= (double) C1
; // exact conversion
151 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
152 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
154 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
155 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
160 if (exp
>= 0) { // -exp <= 0
161 // the argument is an integer already
167 case ROUNDING_TO_NEAREST
:
168 if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
169 // need to shift right -exp digits from the coefficient; exp will be 0
170 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
171 // chop off ind digits from the lower part of C1
172 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
173 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
174 C1
= C1
+ __bid_midpoint64
[ind
- 1];
175 // calculate C* and f*
176 // C* is actually floor(C*) in this case
177 // C* and f* need shifting and masking, as shown by
178 // __bid_shiftright128[] and __bid_maskhigh128[]
180 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
181 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
182 // the approximation of 10^(-x) was rounded up to 64 bits
183 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
185 // if (0 < f* < 10^(-x)) then the result is a midpoint
186 // if floor(C*) is even then C* = floor(C*) - logical right
187 // shift; C* has p decimal digits, correct by Prop. 1)
188 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
189 // shift; C* has p decimal digits, correct by Pr. 1)
191 // C* = floor(C*) (logical right shift; C has p decimal digits,
192 // correct by Property 1)
195 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
198 fstar
.w
[0] = P128
.w
[0];
199 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
200 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
201 res
= (P128
.w
[1] >> shift
);
202 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
203 fstar
.w
[0] = P128
.w
[0];
205 // if (0 < f* < 10^(-x)) then the result is a midpoint
206 // since round_to_even, subtract 1 if current result is odd
207 if ((res
& 0x0000000000000001ull
) && (fstar
.w
[1] == 0)
208 && (fstar
.w
[0] < __bid_ten2mk64
[ind
- 1])) {
211 // determine inexactness of the rounding of C*
212 // if (0 < f* - 1/2 < 10^(-x)) then
213 // the result is exact
214 // else // if (f* - 1/2 > T*) then
215 // the result is inexact
217 if (fstar
.w
[0] > 0x8000000000000000ull
) {
218 // f* > 1/2 and the result may be exact
219 // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
220 if ((fstar
.w
[0] - 0x8000000000000000ull
) > __bid_ten2mk64
[ind
- 1]) {
221 // set the inexact flag
222 *pfpsf
|= INEXACT_EXCEPTION
;
223 } // else the result is exact
224 } else { // the result is inexact; f2* <= 1/2
225 // set the inexact flag
226 *pfpsf
|= INEXACT_EXCEPTION
;
228 } else { // if 3 <= ind - 1 <= 21
229 if (fstar
.w
[1] > __bid_one_half128
[ind
- 1]
230 || (fstar
.w
[1] == __bid_one_half128
[ind
- 1]
232 // f2* > 1/2 and the result may be exact
233 // Calculate f2* - 1/2
234 if (fstar
.w
[1] > __bid_one_half128
[ind
- 1]
235 || fstar
.w
[0] > __bid_ten2mk64
[ind
- 1]) {
236 // set the inexact flag
237 *pfpsf
|= INEXACT_EXCEPTION
;
238 } // else the result is exact
239 } else { // the result is inexact; f2* <= 1/2
240 // set the inexact flag
241 *pfpsf
|= INEXACT_EXCEPTION
;
244 // set exponent to zero as it was negative before.
245 res
= x_sign
| 0x31c0000000000000ull
| res
;
247 } else { // if exp < 0 and q + exp < 0
248 // the result is +0 or -0
249 res
= x_sign
| 0x31c0000000000000ull
;
250 *pfpsf
|= INEXACT_EXCEPTION
;
254 case ROUNDING_TIES_AWAY
:
255 if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
256 // need to shift right -exp digits from the coefficient; exp will be 0
257 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
258 // chop off ind digits from the lower part of C1
259 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
260 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
261 C1
= C1
+ __bid_midpoint64
[ind
- 1];
262 // calculate C* and f*
263 // C* is actually floor(C*) in this case
264 // C* and f* need shifting and masking, as shown by
265 // __bid_shiftright128[] and __bid_maskhigh128[]
267 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
268 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
269 // the approximation of 10^(-x) was rounded up to 64 bits
270 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
272 // if (0 < f* < 10^(-x)) then the result is a midpoint
273 // C* = floor(C*) - logical right shift; C* has p decimal digits,
274 // correct by Prop. 1)
276 // C* = floor(C*) (logical right shift; C has p decimal digits,
277 // correct by Property 1)
280 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
283 fstar
.w
[0] = P128
.w
[0];
284 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
285 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
286 res
= (P128
.w
[1] >> shift
);
287 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
288 fstar
.w
[0] = P128
.w
[0];
290 // midpoints are already rounded correctly
291 // determine inexactness of the rounding of C*
292 // if (0 < f* - 1/2 < 10^(-x)) then
293 // the result is exact
294 // else // if (f* - 1/2 > T*) then
295 // the result is inexact
297 if (fstar
.w
[0] > 0x8000000000000000ull
) {
298 // f* > 1/2 and the result may be exact
299 // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
300 if ((fstar
.w
[0] - 0x8000000000000000ull
) > __bid_ten2mk64
[ind
- 1]) {
301 // set the inexact flag
302 *pfpsf
|= INEXACT_EXCEPTION
;
303 } // else the result is exact
304 } else { // the result is inexact; f2* <= 1/2
305 // set the inexact flag
306 *pfpsf
|= INEXACT_EXCEPTION
;
308 } else { // if 3 <= ind - 1 <= 21
309 if (fstar
.w
[1] > __bid_one_half128
[ind
- 1]
310 || (fstar
.w
[1] == __bid_one_half128
[ind
- 1]
312 // f2* > 1/2 and the result may be exact
313 // Calculate f2* - 1/2
314 if (fstar
.w
[1] > __bid_one_half128
[ind
- 1]
315 || fstar
.w
[0] > __bid_ten2mk64
[ind
- 1]) {
316 // set the inexact flag
317 *pfpsf
|= INEXACT_EXCEPTION
;
318 } // else the result is exact
319 } else { // the result is inexact; f2* <= 1/2
320 // set the inexact flag
321 *pfpsf
|= INEXACT_EXCEPTION
;
324 // set exponent to zero as it was negative before.
325 res
= x_sign
| 0x31c0000000000000ull
| res
;
327 } else { // if exp < 0 and q + exp < 0
328 // the result is +0 or -0
329 res
= x_sign
| 0x31c0000000000000ull
;
330 *pfpsf
|= INEXACT_EXCEPTION
;
335 if ((q
+ exp
) > 0) { // exp < 0 and 1 <= -exp < q
336 // need to shift right -exp digits from the coefficient; exp will be 0
337 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
338 // chop off ind digits from the lower part of C1
339 // C1 fits in 64 bits
340 // calculate C* and f*
341 // C* is actually floor(C*) in this case
342 // C* and f* need shifting and masking, as shown by
343 // __bid_shiftright128[] and __bid_maskhigh128[]
345 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
347 // the approximation of 10^(-x) was rounded up to 64 bits
348 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
350 // C* = floor(C*) (logical right shift; C has p decimal digits,
351 // correct by Property 1)
352 // if (0 < f* < 10^(-x)) then the result is exact
355 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
358 fstar
.w
[0] = P128
.w
[0];
359 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
360 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
361 res
= (P128
.w
[1] >> shift
);
362 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
363 fstar
.w
[0] = P128
.w
[0];
365 // if (f* > 10^(-x)) then the result is inexact
366 if ((fstar
.w
[1] != 0) || (fstar
.w
[0] >= __bid_ten2mk64
[ind
- 1])) {
368 // if negative and not exact, increment magnitude
371 *pfpsf
|= INEXACT_EXCEPTION
;
373 // set exponent to zero as it was negative before.
374 res
= x_sign
| 0x31c0000000000000ull
| res
;
376 } else { // if exp < 0 and q + exp <= 0
377 // the result is +0 or -1
379 res
= 0xb1c0000000000001ull
;
381 res
= 0x31c0000000000000ull
;
383 *pfpsf
|= INEXACT_EXCEPTION
;
388 if ((q
+ exp
) > 0) { // exp < 0 and 1 <= -exp < q
389 // need to shift right -exp digits from the coefficient; exp will be 0
390 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
391 // chop off ind digits from the lower part of C1
392 // C1 fits in 64 bits
393 // calculate C* and f*
394 // C* is actually floor(C*) in this case
395 // C* and f* need shifting and masking, as shown by
396 // __bid_shiftright128[] and __bid_maskhigh128[]
398 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
400 // the approximation of 10^(-x) was rounded up to 64 bits
401 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
403 // C* = floor(C*) (logical right shift; C has p decimal digits,
404 // correct by Property 1)
405 // if (0 < f* < 10^(-x)) then the result is exact
408 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
411 fstar
.w
[0] = P128
.w
[0];
412 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
413 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
414 res
= (P128
.w
[1] >> shift
);
415 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
416 fstar
.w
[0] = P128
.w
[0];
418 // if (f* > 10^(-x)) then the result is inexact
419 if ((fstar
.w
[1] != 0) || (fstar
.w
[0] >= __bid_ten2mk64
[ind
- 1])) {
421 // if positive and not exact, increment magnitude
424 *pfpsf
|= INEXACT_EXCEPTION
;
426 // set exponent to zero as it was negative before.
427 res
= x_sign
| 0x31c0000000000000ull
| res
;
429 } else { // if exp < 0 and q + exp <= 0
430 // the result is -0 or +1
432 res
= 0xb1c0000000000000ull
;
434 res
= 0x31c0000000000001ull
;
436 *pfpsf
|= INEXACT_EXCEPTION
;
440 case ROUNDING_TO_ZERO
:
441 if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
442 // need to shift right -exp digits from the coefficient; exp will be 0
443 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
444 // chop off ind digits from the lower part of C1
445 // C1 fits in 127 bits
446 // calculate C* and f*
447 // C* is actually floor(C*) in this case
448 // C* and f* need shifting and masking, as shown by
449 // __bid_shiftright128[] and __bid_maskhigh128[]
451 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
453 // the approximation of 10^(-x) was rounded up to 64 bits
454 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
456 // C* = floor(C*) (logical right shift; C has p decimal digits,
457 // correct by Property 1)
458 // if (0 < f* < 10^(-x)) then the result is exact
461 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
464 fstar
.w
[0] = P128
.w
[0];
465 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
466 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
467 res
= (P128
.w
[1] >> shift
);
468 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
469 fstar
.w
[0] = P128
.w
[0];
471 // if (f* > 10^(-x)) then the result is inexact
472 if ((fstar
.w
[1] != 0) || (fstar
.w
[0] >= __bid_ten2mk64
[ind
- 1])) {
473 *pfpsf
|= INEXACT_EXCEPTION
;
475 // set exponent to zero as it was negative before.
476 res
= x_sign
| 0x31c0000000000000ull
| res
;
478 } else { // if exp < 0 and q + exp < 0
479 // the result is +0 or -0
480 res
= x_sign
| 0x31c0000000000000ull
;
481 *pfpsf
|= INEXACT_EXCEPTION
;
489 /*****************************************************************************
490 * BID64_round_integral_nearest_even
491 ****************************************************************************/
493 #if DECIMAL_CALL_BY_REFERENCE
495 __bid64_round_integral_nearest_even (UINT64
* pres
,
497 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
502 __bid64_round_integral_nearest_even (UINT64 x _EXC_FLAGS_PARAM
503 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
508 int exp
; // unbiased exponent
509 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
517 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
519 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
521 *pfpsf
|= INVALID_EXCEPTION
;
522 // return Quiet (SNaN)
523 res
= x
& 0xfdffffffffffffffull
;
525 // return original input if QNaN or INF, quietize if SNaN
529 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
530 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
531 // if the steering bits are 11 (condition will be 0), then
532 // the exponent is G[0:w+1]
533 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
534 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
535 if (C1
> 9999999999999999ull) { // non-canonical
539 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
540 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
541 C1
= (x
& MASK_BINARY_SIG1
);
544 // if x is 0 or non-canonical
548 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
551 // x is a finite non-zero number (not 0, non-canonical, or special)
553 // return 0 if (exp <= -(p+1))
555 res
= x_sign
| 0x31c0000000000000ull
;
558 // q = nr. of decimal digits in x (1 <= q <= 54)
559 // determine first the nr. of bits in x
560 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
562 } else { // if x < 2^53
563 tmp1
.d
= (double) C1
; // exact conversion
565 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
566 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
568 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
569 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
574 if (exp
>= 0) { // -exp <= 0
575 // the argument is an integer already
578 } else if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
579 // need to shift right -exp digits from the coefficient; the exp will be 0
580 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
581 // chop off ind digits from the lower part of C1
582 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
583 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
584 C1
= C1
+ __bid_midpoint64
[ind
- 1];
585 // calculate C* and f*
586 // C* is actually floor(C*) in this case
587 // C* and f* need shifting and masking, as shown by
588 // __bid_shiftright128[] and __bid_maskhigh128[]
590 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
591 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
592 // the approximation of 10^(-x) was rounded up to 64 bits
593 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
595 // if (0 < f* < 10^(-x)) then the result is a midpoint
596 // if floor(C*) is even then C* = floor(C*) - logical right
597 // shift; C* has p decimal digits, correct by Prop. 1)
598 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
599 // shift; C* has p decimal digits, correct by Pr. 1)
601 // C* = floor(C*) (logical right shift; C has p decimal digits,
602 // correct by Property 1)
605 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
608 fstar
.w
[0] = P128
.w
[0];
609 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
610 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
611 res
= (P128
.w
[1] >> shift
);
612 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
613 fstar
.w
[0] = P128
.w
[0];
615 // if (0 < f* < 10^(-x)) then the result is a midpoint
616 // since round_to_even, subtract 1 if current result is odd
617 if ((res
& 0x0000000000000001ull
) && (fstar
.w
[1] == 0)
618 && (fstar
.w
[0] < __bid_ten2mk64
[ind
- 1])) {
621 // set exponent to zero as it was negative before.
622 res
= x_sign
| 0x31c0000000000000ull
| res
;
624 } else { // if exp < 0 and q + exp < 0
625 // the result is +0 or -0
626 res
= x_sign
| 0x31c0000000000000ull
;
631 /*****************************************************************************
632 * BID64_round_integral_negative
633 *****************************************************************************/
635 #if DECIMAL_CALL_BY_REFERENCE
637 __bid64_round_integral_negative (UINT64
* pres
,
639 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
644 __bid64_round_integral_negative (UINT64 x _EXC_FLAGS_PARAM
645 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
650 int exp
; // unbiased exponent
651 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
656 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
660 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
662 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
664 *pfpsf
|= INVALID_EXCEPTION
;
665 // return Quiet (SNaN)
666 res
= x
& 0xfdffffffffffffffull
;
668 // return original input if QNaN or INF, quietize if SNaN
672 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
673 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
674 // if the steering bits are 11 (condition will be 0), then
675 // the exponent is G[0:w+1]
676 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
677 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
678 if (C1
> 9999999999999999ull) { // non-canonical
682 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
683 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
684 C1
= (x
& MASK_BINARY_SIG1
);
687 // if x is 0 or non-canonical
691 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
694 // x is a finite non-zero number (not 0, non-canonical, or special)
696 // return 0 if (exp <= -p)
699 res
= 0xb1c0000000000001ull
;
701 res
= 0x31c0000000000000ull
;
705 // q = nr. of decimal digits in x (1 <= q <= 54)
706 // determine first the nr. of bits in x
707 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
709 } else { // if x < 2^53
710 tmp1
.d
= (double) C1
; // exact conversion
712 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
713 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
715 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
716 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
721 if (exp
>= 0) { // -exp <= 0
722 // the argument is an integer already
725 } else if ((q
+ exp
) > 0) { // exp < 0 and 1 <= -exp < q
726 // need to shift right -exp digits from the coefficient; the exp will be 0
727 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
728 // chop off ind digits from the lower part of C1
729 // C1 fits in 64 bits
730 // calculate C* and f*
731 // C* is actually floor(C*) in this case
732 // C* and f* need shifting and masking, as shown by
733 // __bid_shiftright128[] and __bid_maskhigh128[]
735 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
737 // the approximation of 10^(-x) was rounded up to 64 bits
738 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
740 // C* = floor(C*) (logical right shift; C has p decimal digits,
741 // correct by Property 1)
742 // if (0 < f* < 10^(-x)) then the result is exact
745 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
748 fstar
.w
[0] = P128
.w
[0];
749 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
750 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
751 res
= (P128
.w
[1] >> shift
);
752 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
753 fstar
.w
[0] = P128
.w
[0];
755 // if (f* > 10^(-x)) then the result is inexact
757 && ((fstar
.w
[1] != 0) || (fstar
.w
[0] >= __bid_ten2mk64
[ind
- 1]))) {
758 // if negative and not exact, increment magnitude
761 // set exponent to zero as it was negative before.
762 res
= x_sign
| 0x31c0000000000000ull
| res
;
764 } else { // if exp < 0 and q + exp <= 0
765 // the result is +0 or -1
767 res
= 0xb1c0000000000001ull
;
769 res
= 0x31c0000000000000ull
;
775 /*****************************************************************************
776 * BID64_round_integral_positive
777 ****************************************************************************/
779 #if DECIMAL_CALL_BY_REFERENCE
781 __bid64_round_integral_positive (UINT64
* pres
,
783 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
788 __bid64_round_integral_positive (UINT64 x _EXC_FLAGS_PARAM
789 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
794 int exp
; // unbiased exponent
795 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
800 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
804 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
806 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
808 *pfpsf
|= INVALID_EXCEPTION
;
809 // return Quiet (SNaN)
810 res
= x
& 0xfdffffffffffffffull
;
812 // return original input if QNaN or INF, quietize if SNaN
816 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
817 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
818 // if the steering bits are 11 (condition will be 0), then
819 // the exponent is G[0:w+1]
820 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
821 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
822 if (C1
> 9999999999999999ull) { // non-canonical
826 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
827 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
828 C1
= (x
& MASK_BINARY_SIG1
);
831 // if x is 0 or non-canonical
835 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
838 // x is a finite non-zero number (not 0, non-canonical, or special)
840 // return 0 if (exp <= -p)
843 res
= 0xb1c0000000000000ull
;
845 res
= 0x31c0000000000001ull
;
849 // q = nr. of decimal digits in x (1 <= q <= 54)
850 // determine first the nr. of bits in x
851 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
853 } else { // if x < 2^53
854 tmp1
.d
= (double) C1
; // exact conversion
856 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
857 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
859 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
860 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
865 if (exp
>= 0) { // -exp <= 0
866 // the argument is an integer already
869 } else if ((q
+ exp
) > 0) { // exp < 0 and 1 <= -exp < q
870 // need to shift right -exp digits from the coefficient; the exp will be 0
871 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
872 // chop off ind digits from the lower part of C1
873 // C1 fits in 64 bits
874 // calculate C* and f*
875 // C* is actually floor(C*) in this case
876 // C* and f* need shifting and masking, as shown by
877 // __bid_shiftright128[] and __bid_maskhigh128[]
879 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
881 // the approximation of 10^(-x) was rounded up to 64 bits
882 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
884 // C* = floor(C*) (logical right shift; C has p decimal digits,
885 // correct by Property 1)
886 // if (0 < f* < 10^(-x)) then the result is exact
889 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
892 fstar
.w
[0] = P128
.w
[0];
893 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
894 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
895 res
= (P128
.w
[1] >> shift
);
896 fstar
.w
[1] = P128
.w
[1] & __bid_maskhigh128
[ind
- 1];
897 fstar
.w
[0] = P128
.w
[0];
899 // if (f* > 10^(-x)) then the result is inexact
901 && ((fstar
.w
[1] != 0) || (fstar
.w
[0] >= __bid_ten2mk64
[ind
- 1]))) {
902 // if positive and not exact, increment magnitude
905 // set exponent to zero as it was negative before.
906 res
= x_sign
| 0x31c0000000000000ull
| res
;
908 } else { // if exp < 0 and q + exp <= 0
909 // the result is -0 or +1
911 res
= 0xb1c0000000000000ull
;
913 res
= 0x31c0000000000001ull
;
919 /*****************************************************************************
920 * BID64_round_integral_zero
921 ****************************************************************************/
923 #if DECIMAL_CALL_BY_REFERENCE
925 __bid64_round_integral_zero (UINT64
* pres
,
927 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
932 __bid64_round_integral_zero (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
938 int exp
; // unbiased exponent
939 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
944 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
947 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
949 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
951 *pfpsf
|= INVALID_EXCEPTION
;
952 // return Quiet (SNaN)
953 res
= x
& 0xfdffffffffffffffull
;
955 // return original input if QNaN or INF, quietize if SNaN
959 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
960 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
961 // if the steering bits are 11 (condition will be 0), then
962 // the exponent is G[0:w+1]
963 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
964 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
965 if (C1
> 9999999999999999ull) { // non-canonical
969 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
970 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
971 C1
= (x
& MASK_BINARY_SIG1
);
974 // if x is 0 or non-canonical
978 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
981 // x is a finite non-zero number (not 0, non-canonical, or special)
983 // return 0 if (exp <= -p)
985 res
= x_sign
| 0x31c0000000000000ull
;
988 // q = nr. of decimal digits in x (1 <= q <= 54)
989 // determine first the nr. of bits in x
990 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
992 } else { // if x < 2^53
993 tmp1
.d
= (double) C1
; // exact conversion
995 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
996 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
998 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
999 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
1004 if (exp
>= 0) { // -exp <= 0
1005 // the argument is an integer already
1008 } else if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
1009 // need to shift right -exp digits from the coefficient; the exp will be 0
1010 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
1011 // chop off ind digits from the lower part of C1
1012 // C1 fits in 127 bits
1013 // calculate C* and f*
1014 // C* is actually floor(C*) in this case
1015 // C* and f* need shifting and masking, as shown by
1016 // __bid_shiftright128[] and __bid_maskhigh128[]
1018 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1019 // C* = C1 * 10^(-x)
1020 // the approximation of 10^(-x) was rounded up to 64 bits
1021 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
1023 // C* = floor(C*) (logical right shift; C has p decimal digits,
1024 // correct by Property 1)
1025 // if (0 < f* < 10^(-x)) then the result is exact
1026 // n = C* * 10^(e+x)
1028 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1030 // redundant fstar.w[1] = 0;
1031 // redundant fstar.w[0] = P128.w[0];
1032 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1033 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
1034 res
= (P128
.w
[1] >> shift
);
1035 // redundant fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
1036 // redundant fstar.w[0] = P128.w[0];
1038 // if (f* > 10^(-x)) then the result is inexact
1039 // if ((fstar.w[1] != 0) || (fstar.w[0] >= __bid_ten2mk64[ind-1])){
1042 // set exponent to zero as it was negative before.
1043 res
= x_sign
| 0x31c0000000000000ull
| res
;
1045 } else { // if exp < 0 and q + exp < 0
1046 // the result is +0 or -0
1047 res
= x_sign
| 0x31c0000000000000ull
;
1052 /*****************************************************************************
1053 * BID64_round_integral_nearest_away
1054 ****************************************************************************/
1056 #if DECIMAL_CALL_BY_REFERENCE
1058 __bid64_round_integral_nearest_away (UINT64
* pres
,
1060 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1065 __bid64_round_integral_nearest_away (UINT64 x _EXC_FLAGS_PARAM
1066 _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
1069 UINT64 res
= 0x0ull
;
1071 int exp
; // unbiased exponent
1072 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1073 BID_UI64DOUBLE tmp1
;
1079 if ((x
& MASK_INF
) == MASK_INF
) { // x is either INF or NAN
1081 if ((x
& MASK_SNAN
) == MASK_SNAN
) {
1083 *pfpsf
|= INVALID_EXCEPTION
;
1084 // return Quiet (SNaN)
1085 res
= x
& 0xfdffffffffffffffull
;
1087 // return original input if QNaN or INF, quietize if SNaN
1091 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
1092 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
1093 // if the steering bits are 11 (condition will be 0), then
1094 // the exponent is G[0:w+1]
1095 exp
= ((x
& MASK_BINARY_EXPONENT2
) >> 51) - 398;
1096 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
1097 if (C1
> 9999999999999999ull) { // non-canonical
1101 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1102 exp
= ((x
& MASK_BINARY_EXPONENT1
) >> 53) - 398;
1103 C1
= (x
& MASK_BINARY_SIG1
);
1106 // if x is 0 or non-canonical
1110 res
= x_sign
| (((UINT64
) exp
+ 398) << 53);
1113 // x is a finite non-zero number (not 0, non-canonical, or special)
1115 // return 0 if (exp <= -(p+1))
1117 res
= x_sign
| 0x31c0000000000000ull
;
1120 // q = nr. of decimal digits in x (1 <= q <= 54)
1121 // determine first the nr. of bits in x
1122 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
1124 } else { // if x < 2^53
1125 tmp1
.d
= (double) C1
; // exact conversion
1127 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
1128 q
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
1130 q
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
1131 if (C1
>= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
)
1136 if (exp
>= 0) { // -exp <= 0
1137 // the argument is an integer already
1140 } else if ((q
+ exp
) >= 0) { // exp < 0 and 1 <= -exp <= q
1141 // need to shift right -exp digits from the coefficient; the exp will be 0
1142 ind
= -exp
; // 1 <= ind <= 16; ind is a synonym for 'x'
1143 // chop off ind digits from the lower part of C1
1144 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
1145 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
1146 C1
= C1
+ __bid_midpoint64
[ind
- 1];
1147 // calculate C* and f*
1148 // C* is actually floor(C*) in this case
1149 // C* and f* need shifting and masking, as shown by
1150 // __bid_shiftright128[] and __bid_maskhigh128[]
1152 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1153 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
1154 // the approximation of 10^(-x) was rounded up to 64 bits
1155 __mul_64x64_to_128 (P128
, C1
, __bid_ten2mk64
[ind
- 1]);
1157 // if (0 < f* < 10^(-x)) then the result is a midpoint
1158 // C* = floor(C*) - logical right shift; C* has p decimal digits,
1159 // correct by Prop. 1)
1161 // C* = floor(C*) (logical right shift; C has p decimal digits,
1162 // correct by Property 1)
1163 // n = C* * 10^(e+x)
1165 if (ind
- 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1167 } else if (ind
- 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1168 shift
= __bid_shiftright128
[ind
- 1]; // 3 <= shift <= 63
1169 res
= (P128
.w
[1] >> shift
);
1171 // midpoints are already rounded correctly
1172 // set exponent to zero as it was negative before.
1173 res
= x_sign
| 0x31c0000000000000ull
| res
;
1175 } else { // if exp < 0 and q + exp < 0
1176 // the result is +0 or -0
1177 res
= x_sign
| 0x31c0000000000000ull
;