]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/libbid/bid64_round_integral.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / libbid / bid64_round_integral.c
1 /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 #include "bid_internal.h"
25
26 /*****************************************************************************
27 * BID64_round_integral_exact
28 ****************************************************************************/
29
30 #if DECIMAL_CALL_BY_REFERENCE
31 void
32 bid64_round_integral_exact (UINT64 * pres,
33 UINT64 *
34 px _RND_MODE_PARAM _EXC_FLAGS_PARAM
35 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
36 UINT64 x = *px;
37 #if !DECIMAL_GLOBAL_ROUNDING
38 unsigned int rnd_mode = *prnd_mode;
39 #endif
40 #else
41 UINT64
42 bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM
43 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
44 #endif
45
46 UINT64 res = 0xbaddbaddbaddbaddull;
47 UINT64 x_sign;
48 int exp; // unbiased exponent
49 // Note: C1 represents the significand (UINT64)
50 BID_UI64DOUBLE tmp1;
51 int x_nr_bits;
52 int q, ind, shift;
53 UINT64 C1;
54 // UINT64 res is C* at first - represents up to 16 decimal digits <= 54 bits
55 UINT128 fstar = { {0x0ull, 0x0ull} };
56 UINT128 P128;
57
58 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
59
60 // check for NaNs and infinities
61 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
62 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
63 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
64 else
65 x = x & 0xfe03ffffffffffffull; // clear G6-G12
66 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
67 // set invalid flag
68 *pfpsf |= INVALID_EXCEPTION;
69 // return quiet (SNaN)
70 res = x & 0xfdffffffffffffffull;
71 } else { // QNaN
72 res = x;
73 }
74 BID_RETURN (res);
75 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
76 res = x_sign | 0x7800000000000000ull;
77 BID_RETURN (res);
78 }
79 // unpack x
80 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
81 // if the steering bits are 11 (condition will be 0), then
82 // the exponent is G[0:w+1]
83 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
84 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
85 if (C1 > 9999999999999999ull) { // non-canonical
86 C1 = 0;
87 }
88 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
89 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
90 C1 = (x & MASK_BINARY_SIG1);
91 }
92
93 // if x is 0 or non-canonical return 0 preserving the sign bit and
94 // the preferred exponent of MAX(Q(x), 0)
95 if (C1 == 0) {
96 if (exp < 0)
97 exp = 0;
98 res = x_sign | (((UINT64) exp + 398) << 53);
99 BID_RETURN (res);
100 }
101 // x is a finite non-zero number (not 0, non-canonical, or special)
102
103 switch (rnd_mode) {
104 case ROUNDING_TO_NEAREST:
105 case ROUNDING_TIES_AWAY:
106 // return 0 if (exp <= -(p+1))
107 if (exp <= -17) {
108 res = x_sign | 0x31c0000000000000ull;
109 *pfpsf |= INEXACT_EXCEPTION;
110 BID_RETURN (res);
111 }
112 break;
113 case ROUNDING_DOWN:
114 // return 0 if (exp <= -p)
115 if (exp <= -16) {
116 if (x_sign) {
117 res = 0xb1c0000000000001ull;
118 } else {
119 res = 0x31c0000000000000ull;
120 }
121 *pfpsf |= INEXACT_EXCEPTION;
122 BID_RETURN (res);
123 }
124 break;
125 case ROUNDING_UP:
126 // return 0 if (exp <= -p)
127 if (exp <= -16) {
128 if (x_sign) {
129 res = 0xb1c0000000000000ull;
130 } else {
131 res = 0x31c0000000000001ull;
132 }
133 *pfpsf |= INEXACT_EXCEPTION;
134 BID_RETURN (res);
135 }
136 break;
137 case ROUNDING_TO_ZERO:
138 // return 0 if (exp <= -p)
139 if (exp <= -16) {
140 res = x_sign | 0x31c0000000000000ull;
141 *pfpsf |= INEXACT_EXCEPTION;
142 BID_RETURN (res);
143 }
144 break;
145 } // end switch ()
146
147 // q = nr. of decimal digits in x (1 <= q <= 54)
148 // determine first the nr. of bits in x
149 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
150 q = 16;
151 } else { // if x < 2^53
152 tmp1.d = (double) C1; // exact conversion
153 x_nr_bits =
154 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
155 q = nr_digits[x_nr_bits - 1].digits;
156 if (q == 0) {
157 q = nr_digits[x_nr_bits - 1].digits1;
158 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
159 q++;
160 }
161 }
162
163 if (exp >= 0) { // -exp <= 0
164 // the argument is an integer already
165 res = x;
166 BID_RETURN (res);
167 }
168
169 switch (rnd_mode) {
170 case ROUNDING_TO_NEAREST:
171 if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
172 // need to shift right -exp digits from the coefficient; exp will be 0
173 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
174 // chop off ind digits from the lower part of C1
175 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
176 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
177 C1 = C1 + midpoint64[ind - 1];
178 // calculate C* and f*
179 // C* is actually floor(C*) in this case
180 // C* and f* need shifting and masking, as shown by
181 // shiftright128[] and maskhigh128[]
182 // 1 <= x <= 16
183 // kx = 10^(-x) = ten2mk64[ind - 1]
184 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
185 // the approximation of 10^(-x) was rounded up to 64 bits
186 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
187
188 // if (0 < f* < 10^(-x)) then the result is a midpoint
189 // if floor(C*) is even then C* = floor(C*) - logical right
190 // shift; C* has p decimal digits, correct by Prop. 1)
191 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
192 // shift; C* has p decimal digits, correct by Pr. 1)
193 // else
194 // C* = floor(C*) (logical right shift; C has p decimal digits,
195 // correct by Property 1)
196 // n = C* * 10^(e+x)
197
198 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
199 res = P128.w[1];
200 fstar.w[1] = 0;
201 fstar.w[0] = P128.w[0];
202 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
203 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
204 res = (P128.w[1] >> shift);
205 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
206 fstar.w[0] = P128.w[0];
207 }
208 // if (0 < f* < 10^(-x)) then the result is a midpoint
209 // since round_to_even, subtract 1 if current result is odd
210 if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
211 && (fstar.w[0] < ten2mk64[ind - 1])) {
212 res--;
213 }
214 // determine inexactness of the rounding of C*
215 // if (0 < f* - 1/2 < 10^(-x)) then
216 // the result is exact
217 // else // if (f* - 1/2 > T*) then
218 // the result is inexact
219 if (ind - 1 <= 2) {
220 if (fstar.w[0] > 0x8000000000000000ull) {
221 // f* > 1/2 and the result may be exact
222 // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
223 if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
224 // set the inexact flag
225 *pfpsf |= INEXACT_EXCEPTION;
226 } // else the result is exact
227 } else { // the result is inexact; f2* <= 1/2
228 // set the inexact flag
229 *pfpsf |= INEXACT_EXCEPTION;
230 }
231 } else { // if 3 <= ind - 1 <= 21
232 if (fstar.w[1] > onehalf128[ind - 1] ||
233 (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
234 // f2* > 1/2 and the result may be exact
235 // Calculate f2* - 1/2
236 if (fstar.w[1] > onehalf128[ind - 1]
237 || fstar.w[0] > ten2mk64[ind - 1]) {
238 // set the inexact flag
239 *pfpsf |= INEXACT_EXCEPTION;
240 } // else the result is exact
241 } else { // the result is inexact; f2* <= 1/2
242 // set the inexact flag
243 *pfpsf |= INEXACT_EXCEPTION;
244 }
245 }
246 // set exponent to zero as it was negative before.
247 res = x_sign | 0x31c0000000000000ull | res;
248 BID_RETURN (res);
249 } else { // if exp < 0 and q + exp < 0
250 // the result is +0 or -0
251 res = x_sign | 0x31c0000000000000ull;
252 *pfpsf |= INEXACT_EXCEPTION;
253 BID_RETURN (res);
254 }
255 break;
256 case ROUNDING_TIES_AWAY:
257 if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
258 // need to shift right -exp digits from the coefficient; exp will be 0
259 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
260 // chop off ind digits from the lower part of C1
261 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
262 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
263 C1 = C1 + midpoint64[ind - 1];
264 // calculate C* and f*
265 // C* is actually floor(C*) in this case
266 // C* and f* need shifting and masking, as shown by
267 // shiftright128[] and maskhigh128[]
268 // 1 <= x <= 16
269 // kx = 10^(-x) = ten2mk64[ind - 1]
270 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
271 // the approximation of 10^(-x) was rounded up to 64 bits
272 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
273
274 // if (0 < f* < 10^(-x)) then the result is a midpoint
275 // C* = floor(C*) - logical right shift; C* has p decimal digits,
276 // correct by Prop. 1)
277 // else
278 // C* = floor(C*) (logical right shift; C has p decimal digits,
279 // correct by Property 1)
280 // n = C* * 10^(e+x)
281
282 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
283 res = P128.w[1];
284 fstar.w[1] = 0;
285 fstar.w[0] = P128.w[0];
286 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
287 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
288 res = (P128.w[1] >> shift);
289 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
290 fstar.w[0] = P128.w[0];
291 }
292 // midpoints are already rounded correctly
293 // determine inexactness of the rounding of C*
294 // if (0 < f* - 1/2 < 10^(-x)) then
295 // the result is exact
296 // else // if (f* - 1/2 > T*) then
297 // the result is inexact
298 if (ind - 1 <= 2) {
299 if (fstar.w[0] > 0x8000000000000000ull) {
300 // f* > 1/2 and the result may be exact
301 // fstar.w[0] - 0x8000000000000000ull is f* - 1/2
302 if ((fstar.w[0] - 0x8000000000000000ull) > ten2mk64[ind - 1]) {
303 // set the inexact flag
304 *pfpsf |= INEXACT_EXCEPTION;
305 } // else the result is exact
306 } else { // the result is inexact; f2* <= 1/2
307 // set the inexact flag
308 *pfpsf |= INEXACT_EXCEPTION;
309 }
310 } else { // if 3 <= ind - 1 <= 21
311 if (fstar.w[1] > onehalf128[ind - 1] ||
312 (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
313 // f2* > 1/2 and the result may be exact
314 // Calculate f2* - 1/2
315 if (fstar.w[1] > onehalf128[ind - 1]
316 || fstar.w[0] > ten2mk64[ind - 1]) {
317 // set the inexact flag
318 *pfpsf |= INEXACT_EXCEPTION;
319 } // else the result is exact
320 } else { // the result is inexact; f2* <= 1/2
321 // set the inexact flag
322 *pfpsf |= INEXACT_EXCEPTION;
323 }
324 }
325 // set exponent to zero as it was negative before.
326 res = x_sign | 0x31c0000000000000ull | res;
327 BID_RETURN (res);
328 } else { // if exp < 0 and q + exp < 0
329 // the result is +0 or -0
330 res = x_sign | 0x31c0000000000000ull;
331 *pfpsf |= INEXACT_EXCEPTION;
332 BID_RETURN (res);
333 }
334 break;
335 case ROUNDING_DOWN:
336 if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
337 // need to shift right -exp digits from the coefficient; exp will be 0
338 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
339 // chop off ind digits from the lower part of C1
340 // C1 fits in 64 bits
341 // calculate C* and f*
342 // C* is actually floor(C*) in this case
343 // C* and f* need shifting and masking, as shown by
344 // shiftright128[] and maskhigh128[]
345 // 1 <= x <= 16
346 // kx = 10^(-x) = ten2mk64[ind - 1]
347 // C* = C1 * 10^(-x)
348 // the approximation of 10^(-x) was rounded up to 64 bits
349 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
350
351 // C* = floor(C*) (logical right shift; C has p decimal digits,
352 // correct by Property 1)
353 // if (0 < f* < 10^(-x)) then the result is exact
354 // n = C* * 10^(e+x)
355
356 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
357 res = P128.w[1];
358 fstar.w[1] = 0;
359 fstar.w[0] = P128.w[0];
360 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
361 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
362 res = (P128.w[1] >> shift);
363 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
364 fstar.w[0] = P128.w[0];
365 }
366 // if (f* > 10^(-x)) then the result is inexact
367 if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
368 if (x_sign) {
369 // if negative and not exact, increment magnitude
370 res++;
371 }
372 *pfpsf |= INEXACT_EXCEPTION;
373 }
374 // set exponent to zero as it was negative before.
375 res = x_sign | 0x31c0000000000000ull | res;
376 BID_RETURN (res);
377 } else { // if exp < 0 and q + exp <= 0
378 // the result is +0 or -1
379 if (x_sign) {
380 res = 0xb1c0000000000001ull;
381 } else {
382 res = 0x31c0000000000000ull;
383 }
384 *pfpsf |= INEXACT_EXCEPTION;
385 BID_RETURN (res);
386 }
387 break;
388 case ROUNDING_UP:
389 if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
390 // need to shift right -exp digits from the coefficient; exp will be 0
391 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
392 // chop off ind digits from the lower part of C1
393 // C1 fits in 64 bits
394 // calculate C* and f*
395 // C* is actually floor(C*) in this case
396 // C* and f* need shifting and masking, as shown by
397 // shiftright128[] and maskhigh128[]
398 // 1 <= x <= 16
399 // kx = 10^(-x) = ten2mk64[ind - 1]
400 // C* = C1 * 10^(-x)
401 // the approximation of 10^(-x) was rounded up to 64 bits
402 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
403
404 // C* = floor(C*) (logical right shift; C has p decimal digits,
405 // correct by Property 1)
406 // if (0 < f* < 10^(-x)) then the result is exact
407 // n = C* * 10^(e+x)
408
409 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
410 res = P128.w[1];
411 fstar.w[1] = 0;
412 fstar.w[0] = P128.w[0];
413 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
414 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
415 res = (P128.w[1] >> shift);
416 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
417 fstar.w[0] = P128.w[0];
418 }
419 // if (f* > 10^(-x)) then the result is inexact
420 if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
421 if (!x_sign) {
422 // if positive and not exact, increment magnitude
423 res++;
424 }
425 *pfpsf |= INEXACT_EXCEPTION;
426 }
427 // set exponent to zero as it was negative before.
428 res = x_sign | 0x31c0000000000000ull | res;
429 BID_RETURN (res);
430 } else { // if exp < 0 and q + exp <= 0
431 // the result is -0 or +1
432 if (x_sign) {
433 res = 0xb1c0000000000000ull;
434 } else {
435 res = 0x31c0000000000001ull;
436 }
437 *pfpsf |= INEXACT_EXCEPTION;
438 BID_RETURN (res);
439 }
440 break;
441 case ROUNDING_TO_ZERO:
442 if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
443 // need to shift right -exp digits from the coefficient; exp will be 0
444 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
445 // chop off ind digits from the lower part of C1
446 // C1 fits in 127 bits
447 // calculate C* and f*
448 // C* is actually floor(C*) in this case
449 // C* and f* need shifting and masking, as shown by
450 // shiftright128[] and maskhigh128[]
451 // 1 <= x <= 16
452 // kx = 10^(-x) = ten2mk64[ind - 1]
453 // C* = C1 * 10^(-x)
454 // the approximation of 10^(-x) was rounded up to 64 bits
455 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
456
457 // C* = floor(C*) (logical right shift; C has p decimal digits,
458 // correct by Property 1)
459 // if (0 < f* < 10^(-x)) then the result is exact
460 // n = C* * 10^(e+x)
461
462 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
463 res = P128.w[1];
464 fstar.w[1] = 0;
465 fstar.w[0] = P128.w[0];
466 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
467 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
468 res = (P128.w[1] >> shift);
469 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
470 fstar.w[0] = P128.w[0];
471 }
472 // if (f* > 10^(-x)) then the result is inexact
473 if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1])) {
474 *pfpsf |= INEXACT_EXCEPTION;
475 }
476 // set exponent to zero as it was negative before.
477 res = x_sign | 0x31c0000000000000ull | res;
478 BID_RETURN (res);
479 } else { // if exp < 0 and q + exp < 0
480 // the result is +0 or -0
481 res = x_sign | 0x31c0000000000000ull;
482 *pfpsf |= INEXACT_EXCEPTION;
483 BID_RETURN (res);
484 }
485 break;
486 } // end switch ()
487 BID_RETURN (res);
488 }
489
490 /*****************************************************************************
491 * BID64_round_integral_nearest_even
492 ****************************************************************************/
493
494 #if DECIMAL_CALL_BY_REFERENCE
495 void
496 bid64_round_integral_nearest_even (UINT64 * pres,
497 UINT64 *
498 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
499 _EXC_INFO_PARAM) {
500 UINT64 x = *px;
501 #else
502 UINT64
503 bid64_round_integral_nearest_even (UINT64 x _EXC_FLAGS_PARAM
504 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
505 #endif
506
507 UINT64 res = 0xbaddbaddbaddbaddull;
508 UINT64 x_sign;
509 int exp; // unbiased exponent
510 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
511 BID_UI64DOUBLE tmp1;
512 int x_nr_bits;
513 int q, ind, shift;
514 UINT64 C1;
515 UINT128 fstar;
516 UINT128 P128;
517
518 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
519
520 // check for NaNs and infinities
521 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
522 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
523 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
524 else
525 x = x & 0xfe03ffffffffffffull; // clear G6-G12
526 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
527 // set invalid flag
528 *pfpsf |= INVALID_EXCEPTION;
529 // return quiet (SNaN)
530 res = x & 0xfdffffffffffffffull;
531 } else { // QNaN
532 res = x;
533 }
534 BID_RETURN (res);
535 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
536 res = x_sign | 0x7800000000000000ull;
537 BID_RETURN (res);
538 }
539 // unpack x
540 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
541 // if the steering bits are 11 (condition will be 0), then
542 // the exponent is G[0:w+1]
543 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
544 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
545 if (C1 > 9999999999999999ull) { // non-canonical
546 C1 = 0;
547 }
548 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
549 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
550 C1 = (x & MASK_BINARY_SIG1);
551 }
552
553 // if x is 0 or non-canonical
554 if (C1 == 0) {
555 if (exp < 0)
556 exp = 0;
557 res = x_sign | (((UINT64) exp + 398) << 53);
558 BID_RETURN (res);
559 }
560 // x is a finite non-zero number (not 0, non-canonical, or special)
561
562 // return 0 if (exp <= -(p+1))
563 if (exp <= -17) {
564 res = x_sign | 0x31c0000000000000ull;
565 BID_RETURN (res);
566 }
567 // q = nr. of decimal digits in x (1 <= q <= 54)
568 // determine first the nr. of bits in x
569 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
570 q = 16;
571 } else { // if x < 2^53
572 tmp1.d = (double) C1; // exact conversion
573 x_nr_bits =
574 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
575 q = nr_digits[x_nr_bits - 1].digits;
576 if (q == 0) {
577 q = nr_digits[x_nr_bits - 1].digits1;
578 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
579 q++;
580 }
581 }
582
583 if (exp >= 0) { // -exp <= 0
584 // the argument is an integer already
585 res = x;
586 BID_RETURN (res);
587 } else if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
588 // need to shift right -exp digits from the coefficient; the exp will be 0
589 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
590 // chop off ind digits from the lower part of C1
591 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
592 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
593 C1 = C1 + midpoint64[ind - 1];
594 // calculate C* and f*
595 // C* is actually floor(C*) in this case
596 // C* and f* need shifting and masking, as shown by
597 // shiftright128[] and maskhigh128[]
598 // 1 <= x <= 16
599 // kx = 10^(-x) = ten2mk64[ind - 1]
600 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
601 // the approximation of 10^(-x) was rounded up to 64 bits
602 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
603
604 // if (0 < f* < 10^(-x)) then the result is a midpoint
605 // if floor(C*) is even then C* = floor(C*) - logical right
606 // shift; C* has p decimal digits, correct by Prop. 1)
607 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
608 // shift; C* has p decimal digits, correct by Pr. 1)
609 // else
610 // C* = floor(C*) (logical right shift; C has p decimal digits,
611 // correct by Property 1)
612 // n = C* * 10^(e+x)
613
614 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
615 res = P128.w[1];
616 fstar.w[1] = 0;
617 fstar.w[0] = P128.w[0];
618 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
619 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
620 res = (P128.w[1] >> shift);
621 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
622 fstar.w[0] = P128.w[0];
623 }
624 // if (0 < f* < 10^(-x)) then the result is a midpoint
625 // since round_to_even, subtract 1 if current result is odd
626 if ((res & 0x0000000000000001ull) && (fstar.w[1] == 0)
627 && (fstar.w[0] < ten2mk64[ind - 1])) {
628 res--;
629 }
630 // set exponent to zero as it was negative before.
631 res = x_sign | 0x31c0000000000000ull | res;
632 BID_RETURN (res);
633 } else { // if exp < 0 and q + exp < 0
634 // the result is +0 or -0
635 res = x_sign | 0x31c0000000000000ull;
636 BID_RETURN (res);
637 }
638 }
639
640 /*****************************************************************************
641 * BID64_round_integral_negative
642 *****************************************************************************/
643
644 #if DECIMAL_CALL_BY_REFERENCE
645 void
646 bid64_round_integral_negative (UINT64 * pres,
647 UINT64 *
648 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
649 _EXC_INFO_PARAM) {
650 UINT64 x = *px;
651 #else
652 UINT64
653 bid64_round_integral_negative (UINT64 x _EXC_FLAGS_PARAM
654 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
655 #endif
656
657 UINT64 res = 0xbaddbaddbaddbaddull;
658 UINT64 x_sign;
659 int exp; // unbiased exponent
660 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
661 BID_UI64DOUBLE tmp1;
662 int x_nr_bits;
663 int q, ind, shift;
664 UINT64 C1;
665 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
666 UINT128 fstar;
667 UINT128 P128;
668
669 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
670
671 // check for NaNs and infinities
672 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
673 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
674 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
675 else
676 x = x & 0xfe03ffffffffffffull; // clear G6-G12
677 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
678 // set invalid flag
679 *pfpsf |= INVALID_EXCEPTION;
680 // return quiet (SNaN)
681 res = x & 0xfdffffffffffffffull;
682 } else { // QNaN
683 res = x;
684 }
685 BID_RETURN (res);
686 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
687 res = x_sign | 0x7800000000000000ull;
688 BID_RETURN (res);
689 }
690 // unpack x
691 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
692 // if the steering bits are 11 (condition will be 0), then
693 // the exponent is G[0:w+1]
694 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
695 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
696 if (C1 > 9999999999999999ull) { // non-canonical
697 C1 = 0;
698 }
699 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
700 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
701 C1 = (x & MASK_BINARY_SIG1);
702 }
703
704 // if x is 0 or non-canonical
705 if (C1 == 0) {
706 if (exp < 0)
707 exp = 0;
708 res = x_sign | (((UINT64) exp + 398) << 53);
709 BID_RETURN (res);
710 }
711 // x is a finite non-zero number (not 0, non-canonical, or special)
712
713 // return 0 if (exp <= -p)
714 if (exp <= -16) {
715 if (x_sign) {
716 res = 0xb1c0000000000001ull;
717 } else {
718 res = 0x31c0000000000000ull;
719 }
720 BID_RETURN (res);
721 }
722 // q = nr. of decimal digits in x (1 <= q <= 54)
723 // determine first the nr. of bits in x
724 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
725 q = 16;
726 } else { // if x < 2^53
727 tmp1.d = (double) C1; // exact conversion
728 x_nr_bits =
729 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
730 q = nr_digits[x_nr_bits - 1].digits;
731 if (q == 0) {
732 q = nr_digits[x_nr_bits - 1].digits1;
733 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
734 q++;
735 }
736 }
737
738 if (exp >= 0) { // -exp <= 0
739 // the argument is an integer already
740 res = x;
741 BID_RETURN (res);
742 } else if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
743 // need to shift right -exp digits from the coefficient; the exp will be 0
744 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
745 // chop off ind digits from the lower part of C1
746 // C1 fits in 64 bits
747 // calculate C* and f*
748 // C* is actually floor(C*) in this case
749 // C* and f* need shifting and masking, as shown by
750 // shiftright128[] and maskhigh128[]
751 // 1 <= x <= 16
752 // kx = 10^(-x) = ten2mk64[ind - 1]
753 // C* = C1 * 10^(-x)
754 // the approximation of 10^(-x) was rounded up to 64 bits
755 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
756
757 // C* = floor(C*) (logical right shift; C has p decimal digits,
758 // correct by Property 1)
759 // if (0 < f* < 10^(-x)) then the result is exact
760 // n = C* * 10^(e+x)
761
762 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
763 res = P128.w[1];
764 fstar.w[1] = 0;
765 fstar.w[0] = P128.w[0];
766 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
767 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
768 res = (P128.w[1] >> shift);
769 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
770 fstar.w[0] = P128.w[0];
771 }
772 // if (f* > 10^(-x)) then the result is inexact
773 if (x_sign
774 && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
775 // if negative and not exact, increment magnitude
776 res++;
777 }
778 // set exponent to zero as it was negative before.
779 res = x_sign | 0x31c0000000000000ull | res;
780 BID_RETURN (res);
781 } else { // if exp < 0 and q + exp <= 0
782 // the result is +0 or -1
783 if (x_sign) {
784 res = 0xb1c0000000000001ull;
785 } else {
786 res = 0x31c0000000000000ull;
787 }
788 BID_RETURN (res);
789 }
790 }
791
792 /*****************************************************************************
793 * BID64_round_integral_positive
794 ****************************************************************************/
795
796 #if DECIMAL_CALL_BY_REFERENCE
797 void
798 bid64_round_integral_positive (UINT64 * pres,
799 UINT64 *
800 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
801 _EXC_INFO_PARAM) {
802 UINT64 x = *px;
803 #else
804 UINT64
805 bid64_round_integral_positive (UINT64 x _EXC_FLAGS_PARAM
806 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
807 #endif
808
809 UINT64 res = 0xbaddbaddbaddbaddull;
810 UINT64 x_sign;
811 int exp; // unbiased exponent
812 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
813 BID_UI64DOUBLE tmp1;
814 int x_nr_bits;
815 int q, ind, shift;
816 UINT64 C1;
817 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
818 UINT128 fstar;
819 UINT128 P128;
820
821 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
822
823 // check for NaNs and infinities
824 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
825 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
826 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
827 else
828 x = x & 0xfe03ffffffffffffull; // clear G6-G12
829 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
830 // set invalid flag
831 *pfpsf |= INVALID_EXCEPTION;
832 // return quiet (SNaN)
833 res = x & 0xfdffffffffffffffull;
834 } else { // QNaN
835 res = x;
836 }
837 BID_RETURN (res);
838 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
839 res = x_sign | 0x7800000000000000ull;
840 BID_RETURN (res);
841 }
842 // unpack x
843 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
844 // if the steering bits are 11 (condition will be 0), then
845 // the exponent is G[0:w+1]
846 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
847 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
848 if (C1 > 9999999999999999ull) { // non-canonical
849 C1 = 0;
850 }
851 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
852 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
853 C1 = (x & MASK_BINARY_SIG1);
854 }
855
856 // if x is 0 or non-canonical
857 if (C1 == 0) {
858 if (exp < 0)
859 exp = 0;
860 res = x_sign | (((UINT64) exp + 398) << 53);
861 BID_RETURN (res);
862 }
863 // x is a finite non-zero number (not 0, non-canonical, or special)
864
865 // return 0 if (exp <= -p)
866 if (exp <= -16) {
867 if (x_sign) {
868 res = 0xb1c0000000000000ull;
869 } else {
870 res = 0x31c0000000000001ull;
871 }
872 BID_RETURN (res);
873 }
874 // q = nr. of decimal digits in x (1 <= q <= 54)
875 // determine first the nr. of bits in x
876 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
877 q = 16;
878 } else { // if x < 2^53
879 tmp1.d = (double) C1; // exact conversion
880 x_nr_bits =
881 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
882 q = nr_digits[x_nr_bits - 1].digits;
883 if (q == 0) {
884 q = nr_digits[x_nr_bits - 1].digits1;
885 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
886 q++;
887 }
888 }
889
890 if (exp >= 0) { // -exp <= 0
891 // the argument is an integer already
892 res = x;
893 BID_RETURN (res);
894 } else if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
895 // need to shift right -exp digits from the coefficient; the exp will be 0
896 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
897 // chop off ind digits from the lower part of C1
898 // C1 fits in 64 bits
899 // calculate C* and f*
900 // C* is actually floor(C*) in this case
901 // C* and f* need shifting and masking, as shown by
902 // shiftright128[] and maskhigh128[]
903 // 1 <= x <= 16
904 // kx = 10^(-x) = ten2mk64[ind - 1]
905 // C* = C1 * 10^(-x)
906 // the approximation of 10^(-x) was rounded up to 64 bits
907 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
908
909 // C* = floor(C*) (logical right shift; C has p decimal digits,
910 // correct by Property 1)
911 // if (0 < f* < 10^(-x)) then the result is exact
912 // n = C* * 10^(e+x)
913
914 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
915 res = P128.w[1];
916 fstar.w[1] = 0;
917 fstar.w[0] = P128.w[0];
918 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
919 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
920 res = (P128.w[1] >> shift);
921 fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
922 fstar.w[0] = P128.w[0];
923 }
924 // if (f* > 10^(-x)) then the result is inexact
925 if (!x_sign
926 && ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind - 1]))) {
927 // if positive and not exact, increment magnitude
928 res++;
929 }
930 // set exponent to zero as it was negative before.
931 res = x_sign | 0x31c0000000000000ull | res;
932 BID_RETURN (res);
933 } else { // if exp < 0 and q + exp <= 0
934 // the result is -0 or +1
935 if (x_sign) {
936 res = 0xb1c0000000000000ull;
937 } else {
938 res = 0x31c0000000000001ull;
939 }
940 BID_RETURN (res);
941 }
942 }
943
944 /*****************************************************************************
945 * BID64_round_integral_zero
946 ****************************************************************************/
947
948 #if DECIMAL_CALL_BY_REFERENCE
949 void
950 bid64_round_integral_zero (UINT64 * pres,
951 UINT64 *
952 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
953 _EXC_INFO_PARAM) {
954 UINT64 x = *px;
955 #else
956 UINT64
957 bid64_round_integral_zero (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
958 _EXC_INFO_PARAM) {
959 #endif
960
961 UINT64 res = 0xbaddbaddbaddbaddull;
962 UINT64 x_sign;
963 int exp; // unbiased exponent
964 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
965 BID_UI64DOUBLE tmp1;
966 int x_nr_bits;
967 int q, ind, shift;
968 UINT64 C1;
969 // UINT64 res is C* at first - represents up to 34 decimal digits ~ 113 bits
970 UINT128 P128;
971
972 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
973
974 // check for NaNs and infinities
975 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
976 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
977 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
978 else
979 x = x & 0xfe03ffffffffffffull; // clear G6-G12
980 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
981 // set invalid flag
982 *pfpsf |= INVALID_EXCEPTION;
983 // return quiet (SNaN)
984 res = x & 0xfdffffffffffffffull;
985 } else { // QNaN
986 res = x;
987 }
988 BID_RETURN (res);
989 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
990 res = x_sign | 0x7800000000000000ull;
991 BID_RETURN (res);
992 }
993 // unpack x
994 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
995 // if the steering bits are 11 (condition will be 0), then
996 // the exponent is G[0:w+1]
997 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
998 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
999 if (C1 > 9999999999999999ull) { // non-canonical
1000 C1 = 0;
1001 }
1002 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1003 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1004 C1 = (x & MASK_BINARY_SIG1);
1005 }
1006
1007 // if x is 0 or non-canonical
1008 if (C1 == 0) {
1009 if (exp < 0)
1010 exp = 0;
1011 res = x_sign | (((UINT64) exp + 398) << 53);
1012 BID_RETURN (res);
1013 }
1014 // x is a finite non-zero number (not 0, non-canonical, or special)
1015
1016 // return 0 if (exp <= -p)
1017 if (exp <= -16) {
1018 res = x_sign | 0x31c0000000000000ull;
1019 BID_RETURN (res);
1020 }
1021 // q = nr. of decimal digits in x (1 <= q <= 54)
1022 // determine first the nr. of bits in x
1023 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1024 q = 16;
1025 } else { // if x < 2^53
1026 tmp1.d = (double) C1; // exact conversion
1027 x_nr_bits =
1028 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1029 q = nr_digits[x_nr_bits - 1].digits;
1030 if (q == 0) {
1031 q = nr_digits[x_nr_bits - 1].digits1;
1032 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1033 q++;
1034 }
1035 }
1036
1037 if (exp >= 0) { // -exp <= 0
1038 // the argument is an integer already
1039 res = x;
1040 BID_RETURN (res);
1041 } else if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
1042 // need to shift right -exp digits from the coefficient; the exp will be 0
1043 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1044 // chop off ind digits from the lower part of C1
1045 // C1 fits in 127 bits
1046 // calculate C* and f*
1047 // C* is actually floor(C*) in this case
1048 // C* and f* need shifting and masking, as shown by
1049 // shiftright128[] and maskhigh128[]
1050 // 1 <= x <= 16
1051 // kx = 10^(-x) = ten2mk64[ind - 1]
1052 // C* = C1 * 10^(-x)
1053 // the approximation of 10^(-x) was rounded up to 64 bits
1054 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1055
1056 // C* = floor(C*) (logical right shift; C has p decimal digits,
1057 // correct by Property 1)
1058 // if (0 < f* < 10^(-x)) then the result is exact
1059 // n = C* * 10^(e+x)
1060
1061 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1062 res = P128.w[1];
1063 // redundant fstar.w[1] = 0;
1064 // redundant fstar.w[0] = P128.w[0];
1065 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1066 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
1067 res = (P128.w[1] >> shift);
1068 // redundant fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
1069 // redundant fstar.w[0] = P128.w[0];
1070 }
1071 // if (f* > 10^(-x)) then the result is inexact
1072 // if ((fstar.w[1] != 0) || (fstar.w[0] >= ten2mk64[ind-1])){
1073 // // redundant
1074 // }
1075 // set exponent to zero as it was negative before.
1076 res = x_sign | 0x31c0000000000000ull | res;
1077 BID_RETURN (res);
1078 } else { // if exp < 0 and q + exp < 0
1079 // the result is +0 or -0
1080 res = x_sign | 0x31c0000000000000ull;
1081 BID_RETURN (res);
1082 }
1083 }
1084
1085 /*****************************************************************************
1086 * BID64_round_integral_nearest_away
1087 ****************************************************************************/
1088
1089 #if DECIMAL_CALL_BY_REFERENCE
1090 void
1091 bid64_round_integral_nearest_away (UINT64 * pres,
1092 UINT64 *
1093 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1094 _EXC_INFO_PARAM) {
1095 UINT64 x = *px;
1096 #else
1097 UINT64
1098 bid64_round_integral_nearest_away (UINT64 x _EXC_FLAGS_PARAM
1099 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1100 #endif
1101
1102 UINT64 res = 0xbaddbaddbaddbaddull;
1103 UINT64 x_sign;
1104 int exp; // unbiased exponent
1105 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
1106 BID_UI64DOUBLE tmp1;
1107 int x_nr_bits;
1108 int q, ind, shift;
1109 UINT64 C1;
1110 UINT128 P128;
1111
1112 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1113
1114 // check for NaNs and infinities
1115 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
1116 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
1117 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
1118 else
1119 x = x & 0xfe03ffffffffffffull; // clear G6-G12
1120 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
1121 // set invalid flag
1122 *pfpsf |= INVALID_EXCEPTION;
1123 // return quiet (SNaN)
1124 res = x & 0xfdffffffffffffffull;
1125 } else { // QNaN
1126 res = x;
1127 }
1128 BID_RETURN (res);
1129 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
1130 res = x_sign | 0x7800000000000000ull;
1131 BID_RETURN (res);
1132 }
1133 // unpack x
1134 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1135 // if the steering bits are 11 (condition will be 0), then
1136 // the exponent is G[0:w+1]
1137 exp = ((x & MASK_BINARY_EXPONENT2) >> 51) - 398;
1138 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1139 if (C1 > 9999999999999999ull) { // non-canonical
1140 C1 = 0;
1141 }
1142 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS)
1143 exp = ((x & MASK_BINARY_EXPONENT1) >> 53) - 398;
1144 C1 = (x & MASK_BINARY_SIG1);
1145 }
1146
1147 // if x is 0 or non-canonical
1148 if (C1 == 0) {
1149 if (exp < 0)
1150 exp = 0;
1151 res = x_sign | (((UINT64) exp + 398) << 53);
1152 BID_RETURN (res);
1153 }
1154 // x is a finite non-zero number (not 0, non-canonical, or special)
1155
1156 // return 0 if (exp <= -(p+1))
1157 if (exp <= -17) {
1158 res = x_sign | 0x31c0000000000000ull;
1159 BID_RETURN (res);
1160 }
1161 // q = nr. of decimal digits in x (1 <= q <= 54)
1162 // determine first the nr. of bits in x
1163 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1164 q = 16;
1165 } else { // if x < 2^53
1166 tmp1.d = (double) C1; // exact conversion
1167 x_nr_bits =
1168 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1169 q = nr_digits[x_nr_bits - 1].digits;
1170 if (q == 0) {
1171 q = nr_digits[x_nr_bits - 1].digits1;
1172 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
1173 q++;
1174 }
1175 }
1176
1177 if (exp >= 0) { // -exp <= 0
1178 // the argument is an integer already
1179 res = x;
1180 BID_RETURN (res);
1181 } else if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
1182 // need to shift right -exp digits from the coefficient; the exp will be 0
1183 ind = -exp; // 1 <= ind <= 16; ind is a synonym for 'x'
1184 // chop off ind digits from the lower part of C1
1185 // C1 = C1 + 1/2 * 10^x where the result C1 fits in 64 bits
1186 // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
1187 C1 = C1 + midpoint64[ind - 1];
1188 // calculate C* and f*
1189 // C* is actually floor(C*) in this case
1190 // C* and f* need shifting and masking, as shown by
1191 // shiftright128[] and maskhigh128[]
1192 // 1 <= x <= 16
1193 // kx = 10^(-x) = ten2mk64[ind - 1]
1194 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
1195 // the approximation of 10^(-x) was rounded up to 64 bits
1196 __mul_64x64_to_128 (P128, C1, ten2mk64[ind - 1]);
1197
1198 // if (0 < f* < 10^(-x)) then the result is a midpoint
1199 // C* = floor(C*) - logical right shift; C* has p decimal digits,
1200 // correct by Prop. 1)
1201 // else
1202 // C* = floor(C*) (logical right shift; C has p decimal digits,
1203 // correct by Property 1)
1204 // n = C* * 10^(e+x)
1205
1206 if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
1207 res = P128.w[1];
1208 } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
1209 shift = shiftright128[ind - 1]; // 3 <= shift <= 63
1210 res = (P128.w[1] >> shift);
1211 }
1212 // midpoints are already rounded correctly
1213 // set exponent to zero as it was negative before.
1214 res = x_sign | 0x31c0000000000000ull | res;
1215 BID_RETURN (res);
1216 } else { // if exp < 0 and q + exp < 0
1217 // the result is +0 or -0
1218 res = x_sign | 0x31c0000000000000ull;
1219 BID_RETURN (res);
1220 }
1221 }