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 #if DECIMAL_CALL_BY_REFERENCE
33 __bid128_mul (UINT128
* pres
, UINT128
* px
,
35 py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
37 UINT128 x
= *px
, y
= *py
;
39 #if !DECIMAL_GLOBAL_ROUNDING
40 unsigned int rnd_mode
= *prnd_mode
;
45 __bid128_mul (UINT128 x
,
46 UINT128 y _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
51 UINT64 x_sign
, y_sign
, sign
;
54 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
55 // Note: C2.w[1], C2.w[0] represent y_signif_hi, y_signif_lo (all are UINT64)
57 BID_UI64DOUBLE tmp1
, tmp2
;
58 int x_nr_bits
, y_nr_bits
;
59 int q1
, q2
, ind
, shift
;
61 UINT128 Cstar
; // C* represents up to 34 decimal digits ~ 113 bits
64 UINT128 P128
, R128
; // for underflow path
65 UINT192 P192
, R192
; // for underflow path
66 UINT256 C
, P256
, R256
;
69 int incr_exp
= 0; // for underflow path
70 int incr_exp1
= 0; // for underflow path
71 int tmp_fpa
= 0; // if possible underflow and q>=34, use to undo the rounding
75 int is_midpoint_lt_even
= 0, is_midpoint_gt_even
= 0;
76 int is_inexact_lt_midpoint
= 0, is_inexact_gt_midpoint
= 0;
77 int is_midpoint_lt_even1
= 0, is_midpoint_gt_even1
= 0;
78 int is_inexact_lt_midpoint1
= 0, is_inexact_gt_midpoint1
= 0;
82 // unpack the arguments
84 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
85 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
86 C1_hi
= x
.w
[1] & MASK_COEFF
;
90 y_sign
= y
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
91 y_exp
= y
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
92 C2_hi
= y
.w
[1] & MASK_COEFF
;
94 sign
= x_sign
^ y_sign
;
96 // check for NaN or Infinity
97 if (((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
)
98 || ((y
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
)) {
100 // x is special or y is special
101 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
102 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
104 *pfpsf
|= INVALID_EXCEPTION
;
107 res
.w
[1] = x
.w
[1] & 0xfdffffffffffffffull
;
109 } else { // x is QNaN
110 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
112 *pfpsf
|= INVALID_EXCEPTION
;
119 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
120 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
122 *pfpsf
|= INVALID_EXCEPTION
;
125 res
.w
[1] = y
.w
[1] & 0xfdffffffffffffffull
;
127 } else { // y is QNaN
133 } else { // neither x nor y is NaN; at least one is infinity
134 if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x is infinity
135 if (((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) || (C2_hi
!= 0x0ull
)
136 || (C2_lo
!= 0x0ull
)) {
138 // y is infinity OR y is finite
139 // if same sign, return +inf otherwise return -inf
141 res
.w
[1] = 0x7800000000000000ull
; // +inf
142 res
.w
[0] = 0x0000000000000000ull
;
143 } else { // x and y are infinities of opposite signs
144 res
.w
[1] = 0xf800000000000000ull
; // -inf
145 res
.w
[0] = 0x0000000000000000ull
;
147 } else { // if y is 0
149 *pfpsf
|= INVALID_EXCEPTION
;
151 // return QNaN Indefinite
152 res
.w
[1] = 0x7c00000000000000ull
;
153 res
.w
[0] = 0x0000000000000000ull
;
155 } else { // x is not NaN or infinity, so y must be infinity
156 if ((C1_hi
!= 0x0ull
) || (C1_lo
!= 0x0ull
)) {
159 // if same sign, return +inf otherwise return -inf
161 res
.w
[1] = 0x7800000000000000ull
; // +inf
162 res
.w
[0] = 0x0000000000000000ull
;
163 } else { // y and x are of opposite signs
164 res
.w
[1] = 0xf800000000000000ull
; // -inf
165 res
.w
[0] = 0x0000000000000000ull
;
167 } else { // if x is 0
169 *pfpsf
|= INVALID_EXCEPTION
;
171 // return QNaN Indefinite
172 res
.w
[1] = 0x7c00000000000000ull
;
173 res
.w
[0] = 0x0000000000000000ull
;
179 // test for non-canonical values:
180 // - values whose encoding begins with x00, x01, or x10 and whose
181 // coefficient is larger than 10^34 -1, or
182 // - values whose encoding begins with x1100, x1101, x1110 (if NaNs
183 // and infinitis were eliminated already this test is reduced to
184 // checking for x10x)
186 // test for non-canonical values of the argument x
187 if ((((C1_hi
> 0x0001ed09bead87c0ull
) ||
188 ((C1_hi
== 0x0001ed09bead87c0ull
) && (C1_lo
> 0x378d8e63ffffffffull
))) &&
189 ((x
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
)) ||
190 ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
191 // check for the case where the exponent is shifted right by 2 bits!
192 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
193 x_exp
= (x
.w
[1] << 2) & MASK_EXP
; // same position as for G[0]G[1] != 11
195 x
.w
[1] = x
.w
[1] & 0x8000000000000000ull
; // preserve the sign bit
200 // test for non-canonical values of the argument y
201 if ((((C2_hi
> 0x0001ed09bead87c0ull
)
202 || ((C2_hi
== 0x0001ed09bead87c0ull
)
203 && (C2_lo
> 0x378d8e63ffffffffull
)))
204 && ((y
.w
[1] & 0x6000000000000000ull
) != 0x6000000000000000ull
))
205 || ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
)) {
207 // check for the case where the exponent is shifted right by 2 bits!
208 if ((y
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) {
209 y_exp
= (y
.w
[1] << 2) & MASK_EXP
; // same position as for G[0]G[1] != 11
211 y
.w
[1] = y
.w
[1] & 0x8000000000000000ull
; // preserve the sign bit
216 if (((C1_hi
== 0x0ull
) && (C1_lo
== 0x0ull
)) || ((C2_hi
== 0x0ull
)
217 && (C2_lo
== 0x0ull
))) {
219 // x is 0 and y is not special OR y is 0 and x is not special
220 // if same sign, return +0 otherwise return -0
221 ind
= (x_exp
>> 49) + (y_exp
>> 49) - 6176;
225 ind
= 0x2fff; // 6111 + 6176
226 if ((x
.w
[1] & MASK_SIGN
) == (y
.w
[1] & MASK_SIGN
)) {
227 res
.w
[1] = 0x0000000000000000ull
| ((UINT64
) ind
<< 49); // +0.0
228 res
.w
[0] = 0x0000000000000000ull
;
229 } else { // opposite signs
230 res
.w
[1] = 0x8000000000000000ull
| ((UINT64
) ind
<< 49); // -0.0
231 res
.w
[0] = 0x0000000000000000ull
;
234 } else { // x and y are not special and are not zero
239 // q1 = nr. of decimal digits in x
240 // determine first the nr. of bits in x
242 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
243 // split the 64-bit value in two 32-bit halves to avoid rounding errors
244 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
245 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
247 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
249 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
251 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
252 }} else { // if x < 2^53
253 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
255 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
256 }} else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
257 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
259 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
260 } q1
= __bid_nr_digits
[x_nr_bits
- 1].digits
;
262 q1
= __bid_nr_digits
[x_nr_bits
- 1].digits1
;
263 if (C1
.w
[1] > __bid_nr_digits
[x_nr_bits
- 1].threshold_hi
264 || (C1
.w
[1] == __bid_nr_digits
[x_nr_bits
- 1].threshold_hi
265 && C1
.w
[0] >= __bid_nr_digits
[x_nr_bits
- 1].threshold_lo
))
271 if (C2
.w
[0] >= 0x0020000000000000ull
) { // y >= 2^53
272 // split the 64-bit value in two 32-bit halves to avoid rounding errors
273 if (C2
.w
[0] >= 0x0000000100000000ull
) { // y >= 2^32
274 tmp2
.d
= (double) (C2
.w
[0] >> 32); // exact conversion
276 32 + ((((unsigned int) (tmp2
.ui64
>> 52)) & 0x7ff) - 0x3ff);
278 tmp2
.d
= (double) C2
.w
[0]; // exact conversion
280 ((((unsigned int) (tmp2
.ui64
>> 52)) & 0x7ff) - 0x3ff);
281 }} else { // if y < 2^53
282 tmp2
.d
= (double) C2
.w
[0]; // exact conversion
284 ((((unsigned int) (tmp2
.ui64
>> 52)) & 0x7ff) - 0x3ff);
285 }} else { // C2.w[1] != 0 => nr. bits = 64 + nr_bits (C2.w[1])
286 tmp2
.d
= (double) C2
.w
[1]; // exact conversion
288 64 + ((((unsigned int) (tmp2
.ui64
>> 52)) & 0x7ff) - 0x3ff);
289 } q2
= __bid_nr_digits
[y_nr_bits
].digits
;
291 q2
= __bid_nr_digits
[y_nr_bits
].digits1
;
292 if (C2
.w
[1] > __bid_nr_digits
[y_nr_bits
].threshold_hi
293 || (C2
.w
[1] == __bid_nr_digits
[y_nr_bits
].threshold_hi
294 && C2
.w
[0] >= __bid_nr_digits
[y_nr_bits
].threshold_lo
))
297 // the exact product has either q1 + q2 - 1 or q1 + q2 decimal digits
298 // where 2 <= q1 + q2 <= 68
299 // calculate C' = C1 * C2 and determine q
300 C
.w
[3] = C
.w
[2] = C
.w
[1] = C
.w
[0] = 0;
301 if (q1
+ q2
<= 19) { // if 2 <= q1 + q2 <= 19, C' = C1 * C2 fits in 64 bits
302 C
.w
[0] = C1
.w
[0] * C2
.w
[0];
304 // if C' < 10^(q1+q2-1) then q = q1 + q2 - 1 else q = q1 + q2
305 if (C
.w
[0] < __bid_ten2k64
[q1
+ q2
- 1])
306 q
= q1
+ q2
- 1; // q in [1, 18]
308 q
= q1
+ q2
; // q in [2, 19]
309 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 64;
310 } else if (q1
+ q2
== 20) { // C' = C1 * C2 fits in 64 or 128 bits
311 // q1 <= 19 and q2 <= 19 so both C1 and C2 fit in 64 bits
312 __mul_64x64_to_128MACH (C
, C1
.w
[0], C2
.w
[0]);
314 // if C' < 10^(q1+q2-1) = 10^19 then q = q1+q2-1 = 19 else q = q1+q2 = 20
315 if (C
.w
[1] == 0 && C
.w
[0] < __bid_ten2k64
[19]) { // 19 = q1+q2-1
316 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 64;
317 q
= 19; // 19 = q1 + q2 - 1
321 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 64;
323 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
324 q
= 20; // 20 = q1 + q2
326 } else if (q1
+ q2
<= 38) { // 21 <= q1 + q2 <= 38
327 // C' = C1 * C2 fits in 64 or 128 bits
328 // (64 bits possibly, but only when q1 + q2 = 21 and C' has 20 digits)
329 // at least one of C1, C2 has at most 19 decimal digits & fits in 64 bits
331 __mul_128x64_to_128 (C
, C1
.w
[0], C2
);
333 __mul_128x64_to_128 (C
, C2
.w
[0], C1
);
336 // if C' < 10^(q1+q2-1) then q = q1 + q2 - 1 else q = q1 + q2
337 if (C
.w
[1] < __bid_ten2k128
[q1
+ q2
- 21].w
[1]
338 || (C
.w
[1] == __bid_ten2k128
[q1
+ q2
- 21].w
[1]
339 && C
.w
[0] < __bid_ten2k128
[q1
+ q2
- 21].w
[0])) {
341 // if (C.w[1] == 0) // q = 20, necessarily
342 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 64;
344 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
345 q
= q1
+ q2
- 1; // q in [20, 37]
348 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
349 q
= q1
+ q2
; // q in [21, 38]
351 } else if (q1
+ q2
== 39) { // C' = C1 * C2 fits in 128 or 192 bits
352 // both C1 and C2 fit in 128 bits (actually in 113 bits)
353 // may replace this by 128x128_to192
354 __mul_128x128_to_256 (C
, C1
, C2
); // C.w[3] is 0
355 // if C' < 10^(q1+q2-1) = 10^38 then q = q1+q2-1 = 38 else q = q1+q2 = 39
356 if (C
.w
[2] == 0 && (C
.w
[1] < __bid_ten2k128
[18].w
[1] ||
357 (C
.w
[1] == __bid_ten2k128
[18].w
[1] && C
.w
[0] < __bid_ten2k128
[18].w
[0]))) {
358 // 18 = 38 - 20 = q1+q2-1 - 20
359 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
360 q
= 38; // 38 = q1 + q2 - 1
364 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
366 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
367 q
= 39; // 39 = q1 + q2
369 } else if (q1
+ q2
<= 57) { // 40 <= q1 + q2 <= 57
370 // C' = C1 * C2 fits in 128 or 192 bits
371 // (128 bits possibly, but only when q1 + q2 = 40 and C' has 39 digits)
372 // both C1 and C2 fit in 128 bits (actually in 113 bits); at most one
373 // may fit in 64 bits
374 if (C1
.w
[1] == 0) { // C1 fits in 64 bits
375 // __mul_64x128_full (REShi64, RESlo128, A64, B128)
376 __mul_64x128_full (C
.w
[2], C
, C1
.w
[0], C2
);
377 } else if (C2
.w
[1] == 0) { // C2 fits in 64 bits
378 // __mul_64x128_full (REShi64, RESlo128, A64, B128)
379 __mul_64x128_full (C
.w
[2], C
, C2
.w
[0], C1
);
380 } else { // both C1 and C2 require 128 bits
381 // may use __mul_128x128_to_192 (C.w[2], C.w[0], C2.w[0], C1);
382 __mul_128x128_to_256 (C
, C1
, C2
); // C.w[3] = 0
385 // if C' < 10^(q1+q2-1) then q = q1 + q2 - 1 else q = q1 + q2
386 if (C
.w
[2] < __bid_ten2k256
[q1
+ q2
- 40].w
[2]
387 || (C
.w
[2] == __bid_ten2k256
[q1
+ q2
- 40].w
[2]
388 && (C
.w
[1] < __bid_ten2k256
[q1
+ q2
- 40].w
[1]
389 || (C
.w
[1] == __bid_ten2k256
[q1
+ q2
- 40].w
[1]
390 && C
.w
[0] < __bid_ten2k256
[q1
+ q2
- 40].w
[0])))) {
392 // if (C.w[2] == 0) // q = 39, necessarily
393 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 128;
395 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
396 q
= q1
+ q2
- 1; // q in [39, 56]
399 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
400 q
= q1
+ q2
; // q in [40, 57]
402 } else if (q1
+ q2
== 58) { // C' = C1 * C2 fits in 192 or 256 bits
403 // both C1 and C2 fit in 128 bits (actually in 113 bits); at most one
404 // may fit in 64 bits
405 if (C1
.w
[1] == 0) { // C1 * C2 will fit in 192 bits
406 __mul_64x128_full (C
.w
[2], C
, C1
.w
[0], C2
); // may use 64x128_to_192
407 } else if (C2
.w
[1] == 0) { // C1 * C2 will fit in 192 bits
408 __mul_64x128_full (C
.w
[2], C
, C2
.w
[0], C1
); // may use 64x128_to_192
409 } else { // C1 * C2 will fit in 192 bits or in 256 bits
410 __mul_128x128_to_256 (C
, C1
, C2
);
413 // if C' < 10^(q1+q2-1) = 10^57 then q = q1+q2-1 = 57 else q = q1+q2 = 58
414 if (C
.w
[3] == 0 && (C
.w
[2] < __bid_ten2k256
[18].w
[2] ||
415 (C
.w
[2] == __bid_ten2k256
[18].w
[2] && (C
.w
[1] < __bid_ten2k256
[18].w
[1] ||
416 (C
.w
[1] == __bid_ten2k256
[18].w
[1] && C
.w
[0] < __bid_ten2k256
[18].w
[0]))))) {
417 // 18 = 57 - 39 = q1+q2-1 - 39
418 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
419 q
= 57; // 57 = q1 + q2 - 1
423 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
425 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 256;
426 q
= 58; // 58 = q1 + q2
428 } else { // if 59 <= q1 + q2 <= 68
429 // C' = C1 * C2 fits in 192 or 256 bits
430 // (192 bits possibly, but only when q1 + q2 = 59 and C' has 58 digits)
431 // both C1 and C2 fit in 128 bits (actually in 113 bits); none fits in
433 // may use __mul_128x128_to_192 (C.w[2], C.w[0], C2.w[0], C1);
434 __mul_128x128_to_256 (C
, C1
, C2
); // C.w[3] = 0
435 // if C' < 10^(q1+q2-1) then q = q1 + q2 - 1 else q = q1 + q2
436 if (C
.w
[3] < __bid_ten2k256
[q1
+ q2
- 40].w
[3]
437 || (C
.w
[3] == __bid_ten2k256
[q1
+ q2
- 40].w
[3]
438 && (C
.w
[2] < __bid_ten2k256
[q1
+ q2
- 40].w
[2]
439 || (C
.w
[2] == __bid_ten2k256
[q1
+ q2
- 40].w
[2]
440 && (C
.w
[1] < __bid_ten2k256
[q1
+ q2
- 40].w
[1]
441 || (C
.w
[1] == __bid_ten2k256
[q1
+ q2
- 40].w
[1]
442 && C
.w
[0] < __bid_ten2k256
[q1
+ q2
- 40].w
[0])))))) {
444 // if (C.w[3] == 0) // q = 58, necessarily
445 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192;
447 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 256;
448 q
= q1
+ q2
- 1; // q in [58, 67]
451 // length of C1 * C2 rounded up to a multiple of 64 bits is len = 256;
452 q
= q1
+ q2
; // q in [59, 68]
455 if (((UINT64
) q
<< 49) + x_exp
+ y_exp
<
456 ((UINT64
) P34
<< 49) + EXP_MIN
+ BIN_EXP_BIAS
) {
458 // possible underflow
459 // q + ex + ey < P34 + EMIN <=> q - P34 < EMIN - ex - ey <=> q - P34 < ind
460 goto _underflow_path
;
462 if (q
<= 34) { // 2 <= q <= 34 the result is exact, and fits in 113 bits
463 tmp64
= x_exp
+ y_exp
;
464 if (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) { // possible overflow
465 ind
= (tmp64
- EXP_MAX
- BIN_EXP_BIAS
) >> 49;
466 if (ind
> 34 - q
) { // overflow in all rounding modes
467 // |res| >= 10^p * 10^emax = 10^(p-1) * 10^(emax+1)
468 // assemble the result
469 if (rnd_mode
== ROUNDING_TO_NEAREST
470 || rnd_mode
== ROUNDING_TIES_AWAY
) {
471 res
.w
[1] = sign
| 0x7800000000000000ull
;
473 } else if (rnd_mode
== ROUNDING_DOWN
) {
474 if (sign
) { // res = -inf
475 res
.w
[1] = 0xf800000000000000ull
;
477 } else { // res = +MAXFP
478 res
.w
[1] = 0x5fffed09bead87c0ull
;
479 res
.w
[0] = 0x378d8e63ffffffffull
;
481 } else if (rnd_mode
== ROUNDING_UP
) {
482 if (sign
) { // res = -MAXFP
483 res
.w
[1] = 0xdfffed09bead87c0ull
;
484 res
.w
[0] = 0x378d8e63ffffffffull
;
485 } else { // res = +inf
486 res
.w
[1] = 0x7800000000000000ull
;
489 } else { // if (rnd_mode == ROUNDING_TO_ZERO)
490 // |res| = (10^34 - 1) * 10^6111 = +MAXFP
491 res
.w
[1] = sign
| 0x5fffed09bead87c0ull
;
492 res
.w
[0] = 0x378d8e63ffffffffull
;
495 // set the inexact flag
496 *pfpsf
|= INEXACT_EXCEPTION
;
498 // set the overflow flag
499 *pfpsf
|= OVERFLOW_EXCEPTION
;
503 } else { // tmp64 > EXP_MAX + BIN_EXP_BIAS but
504 // ind = ((tmp64-EXP_MAX-BIN_EXP_BIAS)>>49) <= 34 - q
505 // the exponent will be the maximum exponent
506 // multiply C by 10^ind; the result fits in 34 digits
507 if (ind
<= 19) { // multiply by __bid_ten2k64[ind]
508 if (q
<= 19) { // 64x64 -> 128
509 __mul_64x64_to_128MACH (C
, C
.w
[0], __bid_ten2k64
[ind
]);
510 } else { // 128 x 64 -> 128
511 // may optimize to multiply 64 x 128 -> 128
512 __mul_64x128_full (tmp64
, C
, __bid_ten2k64
[ind
], C
);
514 } else { // if 20 <= ind <= 32 multiply by __bid_ten2k128[ind - 20]
515 // it must be that C.w[1] = 0, as C < 10^14
516 // may optimize to multiply 64 x 128 -> 128
517 __mul_64x128_full (tmp64
, C
, C
.w
[0], __bid_ten2k128
[ind
- 20]);
521 res
.w
[1] |= EXP_MAX
; // EXP MAX
526 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
529 } else if (q
<= 38) { // 35 <= q <= 38; exact coefficient fits in 128 bits
530 // C = C + 1/2 * 10^x where the result C fits in 127 bits
533 C
.w
[0] = C
.w
[0] + __bid_midpoint64
[ind
];
537 // x = q - p = q - 34, 1 <= x <= 4
538 // kx = 10^(-x) = __bid_ten2mk128M[ind]
539 // C* = (C + 1/2 * 10^x) * 10^(-x)
540 // the approximation of 10^(-x) was rounded up to 128 bits
541 __mul_128x128_to_256 (P256
, C
, __bid_ten2mk128M
[ind
]);
542 Cstar
.w
[1] = P256
.w
[3];
543 Cstar
.w
[0] = P256
.w
[2];
544 fstar
.w
[2] = Cstar
.w
[0] & __bid_maskhigh128M
[ind
]; // fstar.w[3|4|5]=0
545 fstar
.w
[1] = P256
.w
[1];
546 fstar
.w
[0] = P256
.w
[0];
548 // calculate C* and f*
549 // C* is actually floor(C*) in this case
550 // C* and f* need shifting and masking, as shown by
551 // __bid_shiftright128M[] and __bid_maskhigh128M[]
552 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128truncM[ind], e.g.
553 // if x=1, T*=__bid_ten2mk128truncM[0]=0xcccccccccccccccccccccccccccccccc
554 // if (0 < f* < 10^(-x)) then the result is a midpoint
555 // if floor(C*) is even then C* = floor(C*) - logical right
556 // shift; C* has p decimal digits, correct by Prop. 1)
557 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
558 // shift; C* has p decimal digits, correct by Pr. 1)
560 // C* = floor(C*) (logical right shift; C has p decimal digits,
561 // correct by Property 1)
564 // shift right C* by Ex-128 = __bid_shiftright128M[ind]
565 shift
= __bid_shiftright128M
[ind
]; // 3 <= shift <= 13
566 Cstar
.w
[0] = (Cstar
.w
[0] >> shift
) | (Cstar
.w
[1] << (64 - shift
));
567 Cstar
.w
[1] = (Cstar
.w
[1] >> shift
);
569 // determine inexactness of the rounding of C*
570 // if (0 < f* - 1/2 < 10^(-x)) then
571 // the result is exact
572 // else // if (f* - 1/2 > T*) then
573 // the result is inexact
574 if (fstar
.w
[2] > __bid_one_half128M
[ind
]
575 || (fstar
.w
[2] == __bid_one_half128M
[ind
]
576 && (fstar
.w
[1] || fstar
.w
[0]))) {
578 // f* > 1/2 and the result may be exact
579 // Calculate f* - 1/2
580 tmp64
= fstar
.w
[2] - __bid_one_half128M
[ind
];
581 if (tmp64
|| fstar
.w
[1] > __bid_ten2mk128truncM
[ind
].w
[1] ||
582 (fstar
.w
[1] == __bid_ten2mk128truncM
[ind
].w
[1] &&
583 fstar
.w
[0] > __bid_ten2mk128truncM
[ind
].w
[0])) { // f* - 1/2 > 10^(-x)
584 // set the inexact flag
585 *pfpsf
|= INEXACT_EXCEPTION
;
586 is_inexact_lt_midpoint
= 1;
587 } // else the result is exact
588 } else { // the result is inexact; f2* <= 1/2
589 // set the inexact flag
590 *pfpsf
|= INEXACT_EXCEPTION
;
592 is_inexact_gt_midpoint
= 1;
595 // check for midpoints (could do this before determining inexactness)
596 if ((fstar
.w
[2] == 0) && (fstar
.w
[1] || fstar
.w
[0])
597 && (fstar
.w
[1] < __bid_ten2mk128truncM
[ind
].w
[1]
598 || (fstar
.w
[1] == __bid_ten2mk128truncM
[ind
].w
[1]
599 && fstar
.w
[0] <= __bid_ten2mk128truncM
[ind
].w
[0]))) {
601 // the result is a midpoint
602 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
603 // if floor(C*) is odd C = floor(C*) - 1; the result may be 0
604 Cstar
.w
[0]--; // Cstar.w[0] is now even
607 is_midpoint_gt_even
= 1;
608 is_inexact_lt_midpoint
= 0;
609 is_inexact_gt_midpoint
= 0;
610 } else { // else MP in [ODD, EVEN]
611 is_midpoint_lt_even
= 1;
612 is_inexact_lt_midpoint
= 0;
613 is_inexact_gt_midpoint
= 0;
616 // check for rounding overflow
617 if (Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
618 Cstar
.w
[0] == 0x378d8e6400000000ull
) { // if Cstar = 10^34
619 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 2) << 49);
620 Cstar
.w
[1] = 0x0000314dc6448d93ull
; // Cstar = 10^33
621 Cstar
.w
[0] = 0x38c15b0a00000000ull
;
623 // if rounding overflow made the exponent equal to emin, set underflow
624 if (tmp64
== EXP_MIN
+ BIN_EXP_BIAS
)
625 *pfpsf
|= UNDERFLOW_EXCEPTION
;
626 } else { // 10^33 <= Cstar <= 10^34 - 1
627 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 1) << 49); // ind+1 = q-34
629 if (tmp64
>= EXP_MAX
+ BIN_EXP_BIAS
) { // possibble overflow
630 // exp >= emax for the result rounded to nearest even
631 if (rnd_mode
== ROUNDING_TO_NEAREST
632 || rnd_mode
== ROUNDING_TIES_AWAY
) {
633 if (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) {
635 // |res| >= 10^(p-1) * 10^(emax+1) <=> exp >= emax+1
636 res
.w
[1] = sign
| 0x7800000000000000ull
; // +/-inf
638 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
639 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
641 } else { // not overflow
642 res
.w
[0] = Cstar
.w
[0];
643 res
.w
[1] = Cstar
.w
[1];
644 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
646 } else if (rnd_mode
== ROUNDING_DOWN
) {
647 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
648 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
649 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
650 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
651 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
654 res
.w
[1] = 0x5fffed09bead87c0ull
;
655 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
656 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
657 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
659 } else if (sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
660 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
661 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
662 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
663 is_inexact_lt_midpoint
))) {
664 res
.w
[1] = 0xf800000000000000ull
; // -inf
666 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
667 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
669 } else { // not overflow
670 res
.w
[0] = Cstar
.w
[0];
671 res
.w
[1] = Cstar
.w
[1];
672 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
674 } else if (rnd_mode
== ROUNDING_UP
) {
675 if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
676 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
677 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
678 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
679 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
681 res
.w
[1] = 0xdfffed09bead87c0ull
;
682 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
683 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
684 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
686 } else if (!sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
687 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
688 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
689 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
690 is_inexact_lt_midpoint
))) {
691 res
.w
[1] = 0x7800000000000000ull
; // inf
693 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
694 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
696 } else { // not overflow
697 res
.w
[0] = Cstar
.w
[0];
698 res
.w
[1] = Cstar
.w
[1];
699 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
701 } else { // if (rnd_mode == ROUNDING_TO_ZERO)
702 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
703 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
704 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
705 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
706 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
708 res
.w
[1] = 0x5fffed09bead87c0ull
;
709 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
710 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
711 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
713 } else if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
714 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
715 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
716 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
717 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
719 res
.w
[1] = 0xdfffed09bead87c0ull
;
720 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
721 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
722 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
724 } else { // not overflow
725 res
.w
[0] = Cstar
.w
[0];
726 res
.w
[1] = Cstar
.w
[1];
727 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
730 if (is_overflow
) { // return for overflow
731 // set the inexact flag
732 *pfpsf
|= INEXACT_EXCEPTION
;
734 // set the overflow flag
735 *pfpsf
|= OVERFLOW_EXCEPTION
;
741 res
.w
[0] = Cstar
.w
[0];
742 res
.w
[1] = Cstar
.w
[1];
743 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
746 } else if (q
<= 57) { // 39 <= q <= 57; exact coefficient takes 128-192 bits
747 // C = C + 1/2 * 10^x where the result C fits in 190 bits
748 // (10^57 - 1 + 1/2 * 10^23 can be represented with 190 bits)
749 // x = q - p = q - 34, 5 <= x <= 23
750 // kx = 10^(-x) = __bid_ten2mk192M[ind]
751 // C* = (C + 1/2 * 10^x) * 10^(-x)
752 // the approximation of 10^(-x) was rounded up to 192 bits
753 ind
= q
- 39; // 0 <= ind <= 18
758 // if 5 <= x <= 19 <=> 0 <= ind <= 14 then
760 // else // if 20 <= x <= 23 <=> 15 <= ind <= 18 then
762 if (ind
<= 14) { // x - 1 = q - 35 = ind + 4 <= 18
763 // add one 64-bit word
764 C
.w
[0] = C
.w
[0] + __bid_midpoint64
[ind
+ 4];
769 __mul_192x192_to_384 (P384
, C
, __bid_ten2mk192M
[ind
])
770 // calculate C* and f*; C* is actually floor(C*) in this case
771 // C* and f* need shifting and masking, as shown by
772 // __bid_shiftright192M[] and __bid_maskhigh192M[]
773 // C* has 128 bits; P384.w[5], P384.w[4], P384.w[3] need to be
774 // shifted right by Ex-192 = __bid_shiftright192M[ind]
775 shift
= __bid_shiftright192M
[ind
]; // 16 <= shift <= 63
776 Cstar
.w
[0] = (P384
.w
[3] >> shift
) | (P384
.w
[4] << (64 - shift
));
777 Cstar
.w
[1] = (P384
.w
[4] >> shift
) | (P384
.w
[5] << (64 - shift
));
780 fstar
.w
[3] = P384
.w
[3] & __bid_maskhigh192M
[ind
];
781 fstar
.w
[2] = P384
.w
[2];
782 fstar
.w
[1] = P384
.w
[1];
783 fstar
.w
[0] = P384
.w
[0];
785 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk192truncM[ind], e.g.
786 // if x=5, T* = __bid_ten2mk192truncM[0] =
787 // 0xa7c5ac471b4784230fcf80dc33721d53cddd6e04c0592103
788 // if (0 < f* < 10^(-x)) then the result is a midpoint
789 // if floor(C*) is even then C* = floor(C*) - logical right
790 // shift; C* has p decimal digits, correct by Prop. 1)
791 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
792 // shift; C* has p decimal digits, correct by Pr. 1)
794 // C* = floor(C*) (logical right shift; C has p decimal digits,
795 // correct by Property 1)
798 // determine inexactness of the rounding of C*
799 // if (0 < f* - 1/2 < T* ~= 10^(-x)) then
800 // the result is exact
801 // else // if (f* - 1/2 >= T*) then
802 // the result is inexact
803 if (fstar
.w
[3] > __bid_one_half192M
[ind
]
804 || (fstar
.w
[3] == __bid_one_half192M
[ind
]
805 && (fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0]))) {
807 // f* > 1/2 and the result may be exact
808 // Calculate f* - 1/2
809 tmp64
= fstar
.w
[3] - __bid_one_half192M
[ind
];
810 if (tmp64
|| fstar
.w
[2] > __bid_ten2mk192truncM
[ind
].w
[2] ||
811 (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2] &&
812 fstar
.w
[1] > __bid_ten2mk192truncM
[ind
].w
[1]) ||
813 (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2] &&
814 fstar
.w
[1] == __bid_ten2mk192truncM
[ind
].w
[1] &&
815 fstar
.w
[0] > __bid_ten2mk192truncM
[ind
].w
[0])) { // f* - 1/2 > 10^(-x)
816 // set the inexact flag
817 *pfpsf
|= INEXACT_EXCEPTION
;
818 is_inexact_lt_midpoint
= 1;
819 } // else the result is exact
820 } else { // the result is inexact; f2* <= 1/2
821 // set the inexact flag
822 *pfpsf
|= INEXACT_EXCEPTION
;
824 is_inexact_gt_midpoint
= 1;
827 // check for midpoints (could do this before determining inexactness)
828 if ((fstar
.w
[3] == 0)
829 && (fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0])
830 && (fstar
.w
[2] < __bid_ten2mk192truncM
[ind
].w
[2]
831 || (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2]
832 && fstar
.w
[1] < __bid_ten2mk192truncM
[ind
].w
[1])
833 || (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2]
834 && fstar
.w
[1] == __bid_ten2mk192truncM
[ind
].w
[1]
835 && fstar
.w
[0] <= __bid_ten2mk192truncM
[ind
].w
[0]))) {
837 // the result is a midpoint
838 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
839 // if floor(C*) is odd C = floor(C*) - 1; the result may be 0
840 Cstar
.w
[0]--; // Cstar.w[0] is now even
843 is_midpoint_gt_even
= 1;
844 is_inexact_lt_midpoint
= 0;
845 is_inexact_gt_midpoint
= 0;
846 } else { // else MP in [ODD, EVEN]
847 is_midpoint_lt_even
= 1;
848 is_inexact_lt_midpoint
= 0;
849 is_inexact_gt_midpoint
= 0;
852 } else { // if ind >= 15 <=> x - 1 = q - 35 = ind + 4 >= 19
853 // add two 64-bit words
854 C
.w
[0] = C
.w
[0] + __bid_midpoint128
[ind
- 15].w
[0];
855 C
.w
[1] = C
.w
[1] + __bid_midpoint128
[ind
- 15].w
[1];
860 __mul_192x192_to_384 (P384
, C
, __bid_ten2mk192M
[ind
])
861 // calculate C* and f*; C* is actually floor(C*) in this case
862 // C* and f* need shifting and masking, as shown by
863 // __bid_shiftright192M[] and __bid_maskhigh192M[]
864 // C* has 128 bits; P384.w[5], P384.w[4], need to be
865 // shifted right by Ex-256 = __bid_shiftright192M[ind]
866 shift
= __bid_shiftright192M
[ind
]; // 2 <= shift <= 12
867 Cstar
.w
[0] = (P384
.w
[4] >> shift
) | (P384
.w
[5] << (64 - shift
));
868 Cstar
.w
[1] = (P384
.w
[5] >> shift
);
871 fstar
.w
[4] = P384
.w
[4] & __bid_maskhigh192M
[ind
];
872 fstar
.w
[3] = P384
.w
[3];
873 fstar
.w
[2] = P384
.w
[2];
874 fstar
.w
[1] = P384
.w
[1];
875 fstar
.w
[0] = P384
.w
[0];
877 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk192truncM[ind], e.g.
878 // if x=23, T* = __bid_ten2mk192truncM[18] =
879 // 0xc16d9a0095928a2775b7053c0f1782938d6f439b43088650
880 // if (0 < f* < 10^(-x)) then the result is a midpoint
881 // if floor(C*) is even then C* = floor(C*) - logical right
882 // shift; C* has p decimal digits, correct by Prop. 1)
883 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
884 // shift; C* has p decimal digits, correct by Pr. 1)
886 // C* = floor(C*) (logical right shift; C has p decimal digits,
887 // correct by Property 1)
890 // determine inexactness of the rounding of C*
891 // if (0 < f* - 1/2 < T* ~= 10^(-x)) then
892 // the result is exact
893 // else // if (f* - 1/2 >= T*) then
894 // the result is inexact
895 if (fstar
.w
[4] > __bid_one_half192M
[ind
]
896 || (fstar
.w
[4] == __bid_one_half192M
[ind
]
897 && (fstar
.w
[3] || fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0]))) {
899 // f* > 1/2 and the result may be exact
900 // Calculate f* - 1/2
901 tmp64
= fstar
.w
[4] - __bid_one_half192M
[ind
];
902 if (tmp64
|| fstar
.w
[3] || fstar
.w
[2] > __bid_ten2mk192truncM
[ind
].w
[2] ||
903 (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2] &&
904 fstar
.w
[1] > __bid_ten2mk192truncM
[ind
].w
[1]) ||
905 (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2] &&
906 fstar
.w
[1] == __bid_ten2mk192truncM
[ind
].w
[1] &&
907 fstar
.w
[0] > __bid_ten2mk192truncM
[ind
].w
[0])) { // f* - 1/2 > 10^(-x)
908 // set the inexact flag
909 *pfpsf
|= INEXACT_EXCEPTION
;
910 is_inexact_lt_midpoint
= 1;
911 } // else the result is exact
912 } else { // the result is inexact; f2* <= 1/2
913 // set the inexact flag
914 *pfpsf
|= INEXACT_EXCEPTION
;
916 is_inexact_gt_midpoint
= 1;
919 // check for midpoints (could do this before determining inexactness)
920 if ((fstar
.w
[4] == 0) && (fstar
.w
[3] == 0)
921 && (fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0])
922 && (fstar
.w
[2] < __bid_ten2mk192truncM
[ind
].w
[2]
923 || (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2]
924 && fstar
.w
[1] < __bid_ten2mk192truncM
[ind
].w
[1])
925 || (fstar
.w
[2] == __bid_ten2mk192truncM
[ind
].w
[2]
926 && fstar
.w
[1] == __bid_ten2mk192truncM
[ind
].w
[1]
927 && fstar
.w
[0] <= __bid_ten2mk192truncM
[ind
].w
[0]))) {
929 // the result is a midpoint
930 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
931 // if floor(C*) is odd C = floor(C*) - 1; the result may be 0
932 Cstar
.w
[0]--; // Cstar.w[0] is now even
935 is_midpoint_gt_even
= 1;
936 is_inexact_lt_midpoint
= 0;
937 is_inexact_gt_midpoint
= 0;
938 } else { // else MP in [ODD, EVEN]
939 is_midpoint_lt_even
= 1;
940 is_inexact_lt_midpoint
= 0;
941 is_inexact_gt_midpoint
= 0;
946 // check for rounding overflow
947 if (Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
948 Cstar
.w
[0] == 0x378d8e6400000000ull
) { // if Cstar = 10^34
949 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 6) << 49);
950 Cstar
.w
[1] = 0x0000314dc6448d93ull
; // Cstar = 10^33
951 Cstar
.w
[0] = 0x38c15b0a00000000ull
;
952 } else { // 10^33 <= Cstar <= 10^34 - 1
953 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 5) << 49); // ind+5 = q-34
955 if (tmp64
>= EXP_MAX
+ BIN_EXP_BIAS
) { // possibble overflow
956 // exp >= emax for the result rounded to nearest even
957 if (rnd_mode
== ROUNDING_TO_NEAREST
958 || rnd_mode
== ROUNDING_TIES_AWAY
) {
959 if (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) {
961 // |res| >= 10^(p-1) * 10^(emax+1) <=> exp >= emax+1
962 res
.w
[1] = sign
| 0x7800000000000000ull
; // +/-inf
964 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
965 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
967 } else { // not overflow
968 res
.w
[0] = Cstar
.w
[0];
969 res
.w
[1] = Cstar
.w
[1];
970 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
972 } else if (rnd_mode
== ROUNDING_DOWN
) {
973 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
974 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
975 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
976 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
977 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
979 res
.w
[1] = 0x5fffed09bead87c0ull
;
980 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
981 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
982 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
984 } else if (sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
985 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
986 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
987 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
988 is_inexact_lt_midpoint
))) {
989 res
.w
[1] = 0xf800000000000000ull
; // -inf
991 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
992 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
994 } else { // not overflow
995 res
.w
[0] = Cstar
.w
[0];
996 res
.w
[1] = Cstar
.w
[1];
997 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
999 } else if (rnd_mode
== ROUNDING_UP
) {
1000 if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1001 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1002 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1003 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1004 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1006 res
.w
[1] = 0xdfffed09bead87c0ull
;
1007 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
1008 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1009 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1011 } else if (!sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
1012 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
1013 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
1014 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
1015 is_inexact_lt_midpoint
))) {
1016 res
.w
[1] = 0x7800000000000000ull
; // inf
1018 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1019 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1021 } else { // not overflow
1022 res
.w
[0] = Cstar
.w
[0];
1023 res
.w
[1] = Cstar
.w
[1];
1024 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1026 } else { // if (rnd_mode == ROUNDING_TO_ZERO)
1027 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1028 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1029 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1030 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1031 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1033 res
.w
[1] = 0x5fffed09bead87c0ull
;
1034 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
1035 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1036 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1038 } else if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1039 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1040 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1041 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1042 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1044 res
.w
[1] = 0xdfffed09bead87c0ull
;
1045 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
1046 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1047 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1049 } else { // not overflow
1050 res
.w
[0] = Cstar
.w
[0];
1051 res
.w
[1] = Cstar
.w
[1];
1052 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1055 if (is_overflow
) { // return for overflow
1056 // set the inexact flag
1057 *pfpsf
|= INEXACT_EXCEPTION
;
1059 // set the overflow flag
1060 *pfpsf
|= OVERFLOW_EXCEPTION
;
1065 res
.w
[0] = Cstar
.w
[0];
1066 res
.w
[1] = Cstar
.w
[1];
1067 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1070 } else { // if (58 <= q <= 68) exact coefficient takes 192-226 bits
1071 // C = C + 1/2 * 10^x where the result C fits in 226 bits
1072 // (10^68 - 1 + 1/2 * 10^34 can be represented with 226 bits)
1073 // x = q - p = q - 34, 24 <= x <= 34
1074 // kx = 10^(-x) = __bid_ten2mk256M[ind]
1075 // C* = (C + 1/2 * 10^x) * 10^(-x)
1076 // the approximation of 10^(-x) was rounded up to 256 bits
1077 ind
= q
- 58; // 0 <= ind <= 10
1082 // f* has 384 bits (more than 320 bits)
1083 // x - 1 = q - 35 = ind + 23
1084 // add two 64-bit words; e.g. for ind=0 <=> q=58, add 1/2*10^24
1085 C
.w
[0] = C
.w
[0] + __bid_midpoint128
[ind
+ 4].w
[0];
1086 C
.w
[1] = C
.w
[1] + __bid_midpoint128
[ind
+ 4].w
[1];
1089 if (C
.w
[1] < tmp64A
)
1093 __mul_256x256_to_512 (P512
, C
, __bid_ten2mk256M
[ind
])
1094 // calculate C* and f*; C* is actually floor(C*) in this case
1095 // C* and f* need shifting and masking, as shown by
1096 // __bid_shiftright256M[] and __bid_maskhigh256M[]
1097 // C* has 128 bits; P512.w[7], P512.w[6], P512.w[5] need to be
1098 // shifted right by Ex-320 = __bid_shiftright256M[ind]
1099 shift
= __bid_shiftright256M
[ind
]; // 15 <= shift <= 48
1102 ((P512
.w
[5] >> 31) >> 1) | ((P512
.w
[6] << 31) << 1);
1104 ((P512
.w
[6] >> 31) >> 1) | ((P512
.w
[7] << 31) << 1);
1106 Cstar
.w
[0] = (P512
.w
[5] >> shift
) | (P512
.w
[6] << (64 - shift
));
1107 Cstar
.w
[1] = (P512
.w
[6] >> shift
) | (P512
.w
[7] << (64 - shift
));
1110 fstar
.w
[5] = P512
.w
[5] & __bid_maskhigh256M
[ind
];
1111 fstar
.w
[4] = P512
.w
[4];
1112 fstar
.w
[3] = P512
.w
[3];
1113 fstar
.w
[2] = P512
.w
[2];
1114 fstar
.w
[1] = P512
.w
[1];
1115 fstar
.w
[0] = P512
.w
[0];
1117 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk256truncM[ind], e.g.
1118 // if x=24, T* = __bid_ten2mk256truncM[0] =
1119 // 0x9abe14cd44753b52c4926a9672793542d78c3615cf3a050cf23472530ce6e3ec =~
1121 // if (0 < f* < 10^(-x)) then the result is a midpoint
1122 // if floor(C*) is even then C* = floor(C*) - logical right
1123 // shift; C* has p decimal digits, correct by Prop. 1)
1124 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
1125 // shift; C* has p decimal digits, correct by Pr. 1)
1127 // C* = floor(C*) (logical right shift; C has p decimal digits,
1128 // correct by Property 1)
1129 // n = C* * 10^(e+x)
1131 // determine inexactness of the rounding of C*
1132 // if (0 < f* - 1/2 < T* ~= 10^(-x)) then
1133 // the result is exact
1134 // else // if (f* - 1/2 >= T*) then
1135 // the result is inexact
1136 if (fstar
.w
[5] > __bid_one_half256M
[ind
]
1137 || (fstar
.w
[5] == __bid_one_half256M
[ind
]
1138 && (fstar
.w
[4] || fstar
.w
[3] || fstar
.w
[2] || fstar
.w
[1]
1141 // f* > 1/2 and the result may be exact
1142 // Calculate f* - 1/2
1143 tmp64
= fstar
.w
[5] - __bid_one_half256M
[ind
]; // tmp64 >= 0
1144 if (tmp64
|| fstar
.w
[4] || fstar
.w
[3] > __bid_ten2mk256truncM
[ind
].w
[3] ||
1145 (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3] &&
1146 fstar
.w
[2] > __bid_ten2mk256truncM
[ind
].w
[2]) ||
1147 (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3] &&
1148 fstar
.w
[2] == __bid_ten2mk256truncM
[ind
].w
[2] &&
1149 fstar
.w
[1] > __bid_ten2mk256truncM
[ind
].w
[1]) ||
1150 (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3] &&
1151 fstar
.w
[2] == __bid_ten2mk256truncM
[ind
].w
[2] &&
1152 fstar
.w
[1] == __bid_ten2mk256truncM
[ind
].w
[1] &&
1153 fstar
.w
[0] > __bid_ten2mk256truncM
[ind
].w
[0])) { // f* - 1/2 > 10^(-x)
1154 // set the inexact flag
1155 *pfpsf
|= INEXACT_EXCEPTION
;
1156 is_inexact_lt_midpoint
= 1;
1157 } // else the result is exact
1158 } else { // the result is inexact; f2* <= 1/2
1159 // set the inexact flag
1160 *pfpsf
|= INEXACT_EXCEPTION
;
1162 is_inexact_gt_midpoint
= 1;
1165 // check for midpoints (could do this before determining inexactness)
1166 if ((fstar
.w
[5] == 0) && (fstar
.w
[4] == 0)
1167 && (fstar
.w
[3] || fstar
.w
[2] || fstar
.w
[1] || fstar
.w
[0])
1168 && (fstar
.w
[3] < __bid_ten2mk256truncM
[ind
].w
[3]
1169 || (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3]
1170 && fstar
.w
[2] < __bid_ten2mk256truncM
[ind
].w
[2])
1171 || (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3]
1172 && fstar
.w
[2] == __bid_ten2mk256truncM
[ind
].w
[2]
1173 && fstar
.w
[1] < __bid_ten2mk256truncM
[ind
].w
[1])
1174 || (fstar
.w
[3] == __bid_ten2mk256truncM
[ind
].w
[3]
1175 && fstar
.w
[2] == __bid_ten2mk256truncM
[ind
].w
[2]
1176 && fstar
.w
[1] == __bid_ten2mk256truncM
[ind
].w
[1]
1177 && fstar
.w
[0] <= __bid_ten2mk256truncM
[ind
].w
[1]))) {
1179 // the result is a midpoint
1180 if (Cstar
.w
[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD]
1181 // if floor(C*) is odd C = floor(C*) - 1; the result may be 0
1182 Cstar
.w
[0]--; // Cstar.w[0] is now even
1185 is_midpoint_gt_even
= 1;
1186 is_inexact_lt_midpoint
= 0;
1187 is_inexact_gt_midpoint
= 0;
1188 } else { // else MP in [ODD, EVEN]
1189 is_midpoint_lt_even
= 1;
1190 is_inexact_lt_midpoint
= 0;
1191 is_inexact_gt_midpoint
= 0;
1194 // check for rounding overflow
1195 if (Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
1196 Cstar
.w
[0] == 0x378d8e6400000000ull
) { // if Cstar = 10^34
1197 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 25) << 49);
1198 Cstar
.w
[1] = 0x0000314dc6448d93ull
; // Cstar = 10^33
1199 Cstar
.w
[0] = 0x38c15b0a00000000ull
;
1200 } else { // 10^33 <= Cstar <= 10^34 - 1
1201 tmp64
= x_exp
+ y_exp
+ ((UINT64
) (ind
+ 24) << 49); // ind+24 = q-34
1203 if (tmp64
>= EXP_MAX
+ BIN_EXP_BIAS
) { // possibble overflow
1204 // exp >= emax for the result rounded to nearest even
1205 if (rnd_mode
== ROUNDING_TO_NEAREST
1206 || rnd_mode
== ROUNDING_TIES_AWAY
) {
1207 if (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) {
1209 // |res| >= 10^(p-1) * 10^(emax+1) <=> exp >= emax+1
1210 res
.w
[1] = sign
| 0x7800000000000000ull
; // +/-inf
1212 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1213 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1215 } else { // not overflow
1216 res
.w
[0] = Cstar
.w
[0];
1217 res
.w
[1] = Cstar
.w
[1];
1218 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1220 } else if (rnd_mode
== ROUNDING_DOWN
) {
1221 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1222 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1223 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1224 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1225 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1227 res
.w
[1] = 0x5fffed09bead87c0ull
;
1228 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
1229 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1230 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1232 } else if (sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
1233 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
1234 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
1235 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
1236 is_inexact_lt_midpoint
))) {
1237 res
.w
[1] = 0xf800000000000000ull
; // -inf
1239 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1240 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1242 } else { // not overflow
1243 res
.w
[0] = Cstar
.w
[0];
1244 res
.w
[1] = Cstar
.w
[1];
1245 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1247 } else if (rnd_mode
== ROUNDING_UP
) {
1248 if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1249 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1250 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1251 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1252 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1254 res
.w
[1] = 0xdfffed09bead87c0ull
;
1255 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
1256 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1257 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1259 } else if (!sign
&& ((tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) ||
1260 ((tmp64
== EXP_MAX
+ BIN_EXP_BIAS
) &&
1261 Cstar
.w
[1] == 0x0001ed09bead87c0ull
&&
1262 Cstar
.w
[0] == 0x378d8e63ffffffffull
&& // (10^34-1) * 10^emax
1263 is_inexact_lt_midpoint
))) {
1264 res
.w
[1] = 0x7800000000000000ull
; // inf
1266 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1267 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1269 } else { // not overflow
1270 res
.w
[0] = Cstar
.w
[0];
1271 res
.w
[1] = Cstar
.w
[1];
1272 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1274 } else { // if (rnd_mode == ROUNDING_TO_ZERO)
1275 if (!sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1276 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1277 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1278 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1279 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1281 res
.w
[1] = 0x5fffed09bead87c0ull
;
1282 res
.w
[0] = 0x378d8e63ffffffffull
; // (10^34-1) * 10^emax
1283 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1284 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1286 } else if (sign
&& (tmp64
> EXP_MAX
+ BIN_EXP_BIAS
) &&
1287 !(tmp64
== EXP_MAX
+ BIN_EXP_BIAS
+ EXP_P1
&&
1288 Cstar
.w
[1] == 0x0000314dc6448d93ull
&&
1289 Cstar
.w
[0] == 0x38c15b0a00000000ull
&& // 10^33 * 10^(emax+1)
1290 (is_midpoint_lt_even
|| is_inexact_gt_midpoint
))) {
1292 res
.w
[1] = 0xdfffed09bead87c0ull
;
1293 res
.w
[0] = 0x378d8e63ffffffffull
; // -(10^34-1) * 10^emax
1294 *pfpsf
|= INEXACT_EXCEPTION
; // set the inexact flag
1295 *pfpsf
|= OVERFLOW_EXCEPTION
; // set the overflow flag
1297 } else { // not overflow
1298 res
.w
[0] = Cstar
.w
[0];
1299 res
.w
[1] = Cstar
.w
[1];
1300 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1303 if (is_overflow
) { // return for overflow
1304 // set the inexact flag
1305 *pfpsf
|= INEXACT_EXCEPTION
;
1307 // set the overflow flag
1308 *pfpsf
|= OVERFLOW_EXCEPTION
;
1314 res
.w
[0] = Cstar
.w
[0];
1315 res
.w
[1] = Cstar
.w
[1];
1316 res
.w
[1] |= (tmp64
- BIN_EXP_BIAS
);
1321 // general correction from RN to RA, RM, RP, RZ
1322 if (rnd_mode
!= ROUNDING_TO_NEAREST
&& !is_overflow
) { // overflow is solved
1323 x_exp
= res
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1324 C1_hi
= res
.w
[1] & MASK_COEFF
;
1326 if ((!sign
&& ((rnd_mode
== ROUNDING_UP
&& is_inexact_lt_midpoint
) ||
1327 ((rnd_mode
== ROUNDING_TIES_AWAY
|| rnd_mode
== ROUNDING_UP
) &&
1328 is_midpoint_gt_even
))) ||
1329 (sign
&& ((rnd_mode
== ROUNDING_DOWN
&& is_inexact_lt_midpoint
) ||
1330 ((rnd_mode
== ROUNDING_TIES_AWAY
|| rnd_mode
== ROUNDING_DOWN
) &&
1331 is_midpoint_gt_even
)))) {
1335 if (C1_lo
== 0) { // rounding overflow in the low 64 bits
1337 if (C1_hi
== 0x0001ed09bead87c0ull
1338 && C1_lo
== 0x378d8e6400000000ull
) {
1340 // C1 = 10^34 => rounding overflow
1341 C1_hi
= 0x0000314dc6448d93ull
;
1342 C1_lo
= 0x38c15b0a00000000ull
; // 10^33
1343 x_exp
= x_exp
+ EXP_P1
;
1346 } else if ((is_midpoint_lt_even
|| is_inexact_gt_midpoint
)
1347 && ((sign
&& (rnd_mode
== ROUNDING_UP
||
1348 rnd_mode
== ROUNDING_TO_ZERO
)) ||
1349 (!sign
&& (rnd_mode
== ROUNDING_DOWN
||
1350 rnd_mode
== ROUNDING_TO_ZERO
)))) {
1354 if (C1_lo
== 0xffffffffffffffffull
)
1357 // check if we crossed into the lower decade
1358 if (C1_hi
== 0x0000314dc6448d93ull
&& C1_lo
== 0x38c15b09ffffffffull
) {
1360 C1_hi
= 0x0001ed09bead87c0ull
; // 10^34 - 1
1361 C1_lo
= 0x378d8e63ffffffffull
;
1362 x_exp
= x_exp
- EXP_P1
; // no underflow (TO CHECK)
1365 ; // exact, the result is already correct
1368 // assemble the result
1369 res
.w
[1] = x_exp
| C1_hi
;
1376 // got here because q - P34 < ind where ind = EMIN - ex - ey
1377 // q is the number of digits in C; ind is the [positive] exponent of the
1378 // negative power of 10 that must multiply C in order to make the result's
1379 // exponent equal to e_min - P34 + 1 = -6176
1381 (int) (((SINT64
) EXP_MIN
+ (SINT64
) BIN_EXP_BIAS
- (SINT64
) x_exp
-
1382 (SINT64
) y_exp
) >> 49);
1384 // q - P34 < ind => -P34 + 1 < ind => -P34 + 2 <= ind
1385 // ind = EMIN - ex - ey < -6176 + 6176 + 6176 = 6176
1386 if (q
< ind
) { // q - ind < 0; result rounds to 0 when rounding to nearest
1387 // set the inexact and underflow flags
1388 *pfpsf
|= (INEXACT_EXCEPTION
| UNDERFLOW_EXCEPTION
);
1389 res
.w
[1] = EXP_MIN
; // EXP_MIN = 0x0
1391 if (rnd_mode
!= ROUNDING_TO_NEAREST
) {
1392 if ((rnd_mode
== ROUNDING_DOWN
&& sign
) ||
1393 (rnd_mode
== ROUNDING_UP
&& !sign
))
1394 res
.w
[0] = 0x0000000000000001ull
;
1396 } else if (q
== ind
) { // q - ind = 0; result rounds to 0 or +/-1*10^EMIN
1397 // set the inexact and underflow flags
1398 *pfpsf
|= (INEXACT_EXCEPTION
| UNDERFLOW_EXCEPTION
);
1400 // if C <= 5*10^(q-1) then C = 0 else C = 1
1402 if (C
.w
[0] == __bid_midpoint64
[q
- 1]) { // C = 0.5 * 10^emin
1403 if (rnd_mode
== ROUNDING_TO_NEAREST
|| (rnd_mode
== ROUNDING_DOWN
1404 && !sign
) || (rnd_mode
== ROUNDING_UP
&& sign
)
1405 || rnd_mode
== ROUNDING_TO_ZERO
) {
1412 } else if (C
.w
[0] < __bid_midpoint64
[q
- 1]) { // C < 0.5 * 10^emin
1413 if (rnd_mode
== ROUNDING_TO_NEAREST
1414 || rnd_mode
== ROUNDING_TIES_AWAY
1415 || (rnd_mode
== ROUNDING_DOWN
&& !sign
)
1416 || (rnd_mode
== ROUNDING_UP
&& sign
)
1417 || rnd_mode
== ROUNDING_TO_ZERO
) {
1424 } else { // C > 0.5 * 10^emin
1425 if (rnd_mode
== ROUNDING_TO_NEAREST
1426 || rnd_mode
== ROUNDING_TIES_AWAY
1427 || (rnd_mode
== ROUNDING_DOWN
&& sign
)
1428 || (rnd_mode
== ROUNDING_UP
&& !sign
)) {
1436 } else if (q
<= 38) { // 20 <= q <= 38
1437 // if q <= P34 = 34 the exact result rounded to P34 digits with unbounded
1438 // exponent will have an exponent smaller than e_min; otherwise if
1439 // 35 <= q <= 38, it depends
1440 if (C
.w
[1] == __bid_midpoint128
[q
- 20].w
[1] &&
1441 C
.w
[0] == __bid_midpoint128
[q
- 20].w
[0]) { // C = 0.5 * 10^emin
1442 if (rnd_mode
== ROUNDING_TO_NEAREST
|| (rnd_mode
== ROUNDING_DOWN
1443 && !sign
) || (rnd_mode
== ROUNDING_UP
&& sign
)
1444 || rnd_mode
== ROUNDING_TO_ZERO
) {
1451 } else if (C
.w
[1] < __bid_midpoint128
[q
- 20].w
[1] ||
1452 (C
.w
[1] == __bid_midpoint128
[q
- 20].w
[1] &&
1453 C
.w
[0] < __bid_midpoint128
[q
- 20].w
[0])) { // C < 0.5 * 10^emin
1454 if (rnd_mode
== ROUNDING_TO_NEAREST
1455 || rnd_mode
== ROUNDING_TIES_AWAY
1456 || (rnd_mode
== ROUNDING_DOWN
&& !sign
)
1457 || (rnd_mode
== ROUNDING_UP
&& sign
)
1458 || rnd_mode
== ROUNDING_TO_ZERO
) {
1465 } else { // C > 0.5 * 10^emin
1466 if (rnd_mode
== ROUNDING_TO_NEAREST
1467 || rnd_mode
== ROUNDING_TIES_AWAY
1468 || (rnd_mode
== ROUNDING_DOWN
&& sign
)
1469 || (rnd_mode
== ROUNDING_UP
&& !sign
)) {
1477 } else if (q
<= 58) { // 39 <= q <= 58
1478 // Note: for q = 58 C may take 256 bits, so need to test C.w[3]
1479 if (C
.w
[3] == 0x0 && C
.w
[2] == __bid_midpoint192
[q
- 39].w
[2] &&
1480 C
.w
[1] == __bid_midpoint192
[q
- 39].w
[1] &&
1481 C
.w
[0] == __bid_midpoint192
[q
- 39].w
[0]) { // C = 0.5 * 10^emin
1482 if (rnd_mode
== ROUNDING_TO_NEAREST
|| (rnd_mode
== ROUNDING_DOWN
1483 && !sign
) || (rnd_mode
== ROUNDING_UP
&& sign
)
1484 || rnd_mode
== ROUNDING_TO_ZERO
) {
1491 } else if ((C
.w
[3] == 0x0 && C
.w
[2] < __bid_midpoint192
[q
- 39].w
[2]) ||
1492 (C
.w
[3] == 0x0 && C
.w
[2] == __bid_midpoint192
[q
- 39].w
[2] &&
1493 C
.w
[1] < __bid_midpoint192
[q
- 39].w
[1]) || (C
.w
[3] == 0x0 &&
1494 C
.w
[2] == __bid_midpoint192
[q
- 39].w
[2] &&
1495 C
.w
[1] == __bid_midpoint192
[q
- 39].w
[1] &&
1496 C
.w
[0] < __bid_midpoint192
[q
- 39].w
[0])) { // C < 0.5 * 10^emin
1497 if (rnd_mode
== ROUNDING_TO_NEAREST
1498 || rnd_mode
== ROUNDING_TIES_AWAY
1499 || (rnd_mode
== ROUNDING_DOWN
&& !sign
)
1500 || (rnd_mode
== ROUNDING_UP
&& sign
)
1501 || rnd_mode
== ROUNDING_TO_ZERO
) {
1508 } else { // C > 0.5 * 10^emin
1509 if (rnd_mode
== ROUNDING_TO_NEAREST
1510 || rnd_mode
== ROUNDING_TIES_AWAY
1511 || (rnd_mode
== ROUNDING_DOWN
&& sign
)
1512 || (rnd_mode
== ROUNDING_UP
&& !sign
)) {
1520 } else { // if (q <= 68), i.e. 59 <= q <= 68
1521 if (C
.w
[3] == __bid_midpoint256
[q
- 59].w
[3] &&
1522 C
.w
[2] == __bid_midpoint256
[q
- 59].w
[2] &&
1523 C
.w
[1] == __bid_midpoint256
[q
- 59].w
[1] &&
1524 C
.w
[0] == __bid_midpoint256
[q
- 59].w
[0]) { // C = 0.5 * 10^emin
1525 if (rnd_mode
== ROUNDING_TO_NEAREST
|| (rnd_mode
== ROUNDING_DOWN
1526 && !sign
) || (rnd_mode
== ROUNDING_UP
&& sign
)
1527 || rnd_mode
== ROUNDING_TO_ZERO
) {
1534 } else if (C
.w
[3] < __bid_midpoint256
[q
- 59].w
[3] ||
1535 (C
.w
[3] == __bid_midpoint256
[q
- 59].w
[3] &&
1536 C
.w
[2] < __bid_midpoint256
[q
- 59].w
[2]) ||
1537 (C
.w
[3] == __bid_midpoint256
[q
- 59].w
[3] &&
1538 C
.w
[2] == __bid_midpoint256
[q
- 59].w
[2] &&
1539 C
.w
[1] < __bid_midpoint256
[q
- 59].w
[1]) ||
1540 (C
.w
[3] == __bid_midpoint256
[q
- 59].w
[3] &&
1541 C
.w
[2] == __bid_midpoint256
[q
- 59].w
[2] &&
1542 C
.w
[1] == __bid_midpoint256
[q
- 59].w
[1] &&
1543 C
.w
[0] < __bid_midpoint256
[q
- 59].w
[0])) { // C < 0.5 * 10^emin
1544 if (rnd_mode
== ROUNDING_TO_NEAREST
1545 || rnd_mode
== ROUNDING_TIES_AWAY
1546 || (rnd_mode
== ROUNDING_DOWN
&& !sign
)
1547 || (rnd_mode
== ROUNDING_UP
&& sign
)
1548 || rnd_mode
== ROUNDING_TO_ZERO
) {
1555 } else { // C > 0.5 * 10^emin
1556 if (rnd_mode
== ROUNDING_TO_NEAREST
1557 || rnd_mode
== ROUNDING_TIES_AWAY
1558 || (rnd_mode
== ROUNDING_DOWN
&& sign
)
1559 || (rnd_mode
== ROUNDING_UP
&& !sign
)) {
1568 } else { // if 0 < q - ind < P34 <=> 1 <= q - ind <= P34 - 1 = 33
1569 // In general -P34 + 2 <= ind <= 6176 => -P34 + 2 <= ind < q =>
1570 // -P34 + 2 <= ind <= q - 1
1571 if (rnd_mode
!= ROUNDING_TO_NEAREST
) {
1572 is_inexact_lt_midpoint
= 0;
1573 is_inexact_gt_midpoint
= 0;
1574 is_midpoint_lt_even
= 0;
1575 is_midpoint_gt_even
= 0;
1577 if (ind
<= 0) { // 0 <= -ind
1578 // the result is exact
1579 res
.w
[1] = (x_exp
+ y_exp
- BIN_EXP_BIAS
) | C
.w
[1];
1582 // because the result is exact the U and I status flags are not set
1585 // if ind > 0 <=> 1 <= ind <= q - 1; must remove ind digits
1586 // from C, which may have up to 68 digits; note that q >= ind + 1 >= 2
1587 // Note: there is no underflow in some cases when the coefficient of
1588 // the result is 10^33 or 10^33 - 1
1589 if (q
<= 18) { // 2 <= q <= 18
1590 __bid_round64_2_18 (q
, ind
, C
.w
[0], &res
.w
[0], &incr_exp
,
1591 &is_midpoint_lt_even
, &is_midpoint_gt_even
,
1592 &is_inexact_lt_midpoint
, &is_inexact_gt_midpoint
);
1595 // multiply by 10; this cannot be 10^33
1596 __mul_64x64_to_128MACH (res
, res
.w
[0], __bid_ten2k64
[1]);
1597 res
.w
[1] |= (UINT64
) EXP_MIN
;
1598 } else { // underflow
1599 res
.w
[1] = (UINT64
) EXP_MIN
;
1601 if (is_midpoint_lt_even
|| is_midpoint_gt_even
1602 || is_inexact_lt_midpoint
|| is_inexact_gt_midpoint
) {
1604 // set the inexact and underflow flags
1605 *pfpsf
|= (INEXACT_EXCEPTION
| UNDERFLOW_EXCEPTION
);
1607 } else if (q
<= 38) { // 19 <= q <= 38
1610 __bid_round128_19_38 (q
, ind
, P128
, &res
, &incr_exp
,
1611 &is_midpoint_lt_even
, &is_midpoint_gt_even
,
1612 &is_inexact_lt_midpoint
,
1613 &is_inexact_gt_midpoint
);
1616 // multiply by 10 and check is this is 10^33, because in that case
1617 // it is possible that this is not underflow
1618 if (q
- ind
<= 19) {
1619 __mul_64x64_to_128MACH (res
, res
.w
[0], __bid_ten2k64
[1]);
1620 } else { // if 20 <= q - ind
1621 __mul_128x64_to_128 (res
, __bid_ten2k64
[1], res
);
1623 if ((q
- ind
+ 1) == P34
) { // the result is 10^(P34-1)
1624 // if the result rounded directly to P34 digits is the same, then
1625 // there is no underflow
1626 __bid_round128_19_38 (q
, ind
- 1, P128
, &R128
, &incr_exp1
,
1627 &is_midpoint_lt_even1
,
1628 &is_midpoint_gt_even1
,
1629 &is_inexact_lt_midpoint1
,
1630 &is_inexact_gt_midpoint1
);
1631 if (res
.w
[1] == R128
.w
[1] && res
.w
[0] == R128
.w
[0]) {
1635 // res.w[1] |= (UINT64)EXP_MIN; // redundant
1636 } else { // underflow
1637 // res.w[1] = (UINT64)EXP_MIN | res.w[1]; // redundant
1639 if (is_midpoint_lt_even
|| is_midpoint_gt_even
1640 || is_inexact_lt_midpoint
|| is_inexact_gt_midpoint
) {
1642 // set the inexact and underflow flags
1643 *pfpsf
|= INEXACT_EXCEPTION
;
1646 *pfpsf
|= UNDERFLOW_EXCEPTION
;
1648 } else if (q
<= 57) { // 39 <= q <= 57
1652 __bid_round192_39_57 (q
, ind
, P192
, &R192
, &incr_exp
,
1653 &is_midpoint_lt_even
, &is_midpoint_gt_even
,
1654 &is_inexact_lt_midpoint
,
1655 &is_inexact_gt_midpoint
);
1658 // multiply by 10 and check is this is 10^33, because in that case
1659 // it is possible that this is not underflow
1660 res
.w
[1] = R192
.w
[1]; // res has q - ind digits
1661 res
.w
[0] = R192
.w
[0];
1662 if (q
- ind
<= 19) {
1663 __mul_64x64_to_128MACH (res
, res
.w
[0], __bid_ten2k64
[1]);
1664 } else { // if 20 <= q - ind
1665 __mul_128x64_to_128 (res
, __bid_ten2k64
[1], res
);
1667 if ((q
- ind
+ 1) == P34
) { // the result is 10^(P34-1)
1668 // if the result rounded directly to P34 digits is the same, then
1669 // there is no underflow
1670 __bid_round192_39_57 (q
, ind
- 1, P192
, &R192
, &incr_exp1
,
1671 &is_midpoint_lt_even1
,
1672 &is_midpoint_gt_even1
,
1673 &is_inexact_lt_midpoint1
,
1674 &is_inexact_gt_midpoint1
);
1675 if (res
.w
[1] == R192
.w
[1] && res
.w
[0] == R192
.w
[0]) {
1679 // res.w[1] |= (UINT64)EXP_MIN; // redundant
1680 } else { // underflow
1681 res
.w
[1] = (UINT64
) EXP_MIN
| R192
.w
[1];
1682 res
.w
[0] = R192
.w
[0];
1684 if (is_midpoint_lt_even
|| is_midpoint_gt_even
1685 || is_inexact_lt_midpoint
|| is_inexact_gt_midpoint
) {
1687 // set the inexact and underflow flags
1688 *pfpsf
|= INEXACT_EXCEPTION
;
1691 *pfpsf
|= UNDERFLOW_EXCEPTION
;
1693 } else if (q
<= 76) { // 58 <= q <= 76 (actually 58 <= q <= 68)
1698 __bid_round256_58_76 (q
, ind
, P256
, &R256
, &incr_exp
,
1699 &is_midpoint_lt_even
, &is_midpoint_gt_even
,
1700 &is_inexact_lt_midpoint
,
1701 &is_inexact_gt_midpoint
);
1704 // multiply by 10 and check is this is 10^33, because in that case
1705 // it is possible that this is not underflow
1706 res
.w
[1] = R256
.w
[1]; // res has q - ind digits
1707 res
.w
[0] = R256
.w
[0];
1708 if (q
- ind
<= 19) {
1709 __mul_64x64_to_128MACH (res
, res
.w
[0], __bid_ten2k64
[1]);
1710 } else { // if 20 <= q - ind
1711 __mul_128x64_to_128 (res
, __bid_ten2k64
[1], res
);
1713 if ((q
- ind
+ 1) == P34
) { // the result is 10^(P34-1)
1714 // if the result rounded directly to P34 digits is the same, then
1715 // there is no underflow
1716 __bid_round256_58_76 (q
, ind
- 1, P256
, &R256
, &incr_exp1
,
1717 &is_midpoint_lt_even1
,
1718 &is_midpoint_gt_even1
,
1719 &is_inexact_lt_midpoint1
,
1720 &is_inexact_gt_midpoint1
);
1721 if (res
.w
[1] == R256
.w
[1] && res
.w
[0] == R256
.w
[0]) {
1725 // res.w[1] |= (UINT64)EXP_MIN; // redundant
1726 } else { // underflow
1727 res
.w
[1] = (UINT64
) EXP_MIN
| R256
.w
[1];
1728 res
.w
[0] = R256
.w
[0];
1730 if (is_midpoint_lt_even
|| is_midpoint_gt_even
1731 || is_inexact_lt_midpoint
|| is_inexact_gt_midpoint
) {
1733 // set the inexact and underflow flags
1734 *pfpsf
|= INEXACT_EXCEPTION
;
1737 *pfpsf
|= UNDERFLOW_EXCEPTION
;
1742 // general correction from RN to RA, RM, RP, RZ
1743 if (rnd_mode
!= ROUNDING_TO_NEAREST
) {
1744 x_exp
= res
.w
[1] & MASK_EXP
; // biased and shifted left 49 bit positions
1745 // this must be e_min
1746 C1_hi
= res
.w
[1] & MASK_COEFF
;
1748 if ((!sign
&& ((rnd_mode
== ROUNDING_UP
&& is_inexact_lt_midpoint
) ||
1749 ((rnd_mode
== ROUNDING_TIES_AWAY
|| rnd_mode
== ROUNDING_UP
) &&
1750 is_midpoint_gt_even
))) ||
1751 (sign
&& ((rnd_mode
== ROUNDING_DOWN
&& is_inexact_lt_midpoint
) ||
1752 ((rnd_mode
== ROUNDING_TIES_AWAY
|| rnd_mode
== ROUNDING_DOWN
) &&
1753 is_midpoint_gt_even
)))) {
1757 if (C1_lo
== 0) { // rounding overflow in the low 64 bits
1759 if (C1_hi
== 0x0001ed09bead87c0ull
1760 && C1_lo
== 0x378d8e6400000000ull
) {
1762 // C1 = 10^34 => rounding overflow (not possible) TO CHECK
1763 C1_hi
= 0x0000314dc6448d93ull
;
1764 C1_lo
= 0x38c15b0a00000000ull
; // 10^33
1765 x_exp
= x_exp
+ EXP_P1
; // this must be e_min
1768 } else if ((is_midpoint_lt_even
|| is_inexact_gt_midpoint
) &&
1770 (rnd_mode
== ROUNDING_UP
|| rnd_mode
== ROUNDING_TO_ZERO
)) ||
1772 (rnd_mode
== ROUNDING_DOWN
|| rnd_mode
== ROUNDING_TO_ZERO
)))) {
1774 // C1 = C1 - 1 (the exponent is emin already)
1776 if (C1_lo
== 0xffffffffffffffffull
)
1779 // cannot cross into the lower decade anymore, but the result can be 0
1781 ; // exact, the result is already correct
1784 // no overflow is possible
1785 // assemble the result
1786 res
.w
[1] = x_exp
| C1_hi
;
1789 // Now fix the case where the general rounding routine returned a non-tiny
1790 // result, but after the correction for rounding modes other than to
1791 // nearest, the result is less in magnitude than 100...0[34] * 10^(-6176)
1792 // (this is due to the fact that the general rounding routine works only
1793 // with rounding to nearest)
1794 if (is_inexact
&& (x_exp
== EXP_MIN
)
1795 && (C1_hi
< 0x0000314dc6448d93ull
1796 || (C1_hi
== 0x0000314dc6448d93ull
1797 && C1_lo
< 0x38c15b0a00000000ull
))) {
1798 *pfpsf
|= UNDERFLOW_EXCEPTION
;