]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/libbid/bid64_to_int64.c
Merged with libbbid branch at revision 126349.
[thirdparty/gcc.git] / libgcc / config / libbid / bid64_to_int64.c
1 /* Copyright (C) 2007 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 2, or (at your option) any later
8 version.
9
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
17 executable.)
18
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
22 for more details.
23
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
27 02110-1301, USA. */
28
29 #include "bid_internal.h"
30
31 /*****************************************************************************
32 * BID64_to_int64_rnint
33 ****************************************************************************/
34
35 #if DECIMAL_CALL_BY_REFERENCE
36 void
37 __bid64_to_int64_rnint (SINT64 * pres, UINT64 * px
38 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
39 _EXC_INFO_PARAM) {
40 UINT64 x = *px;
41 #else
42 SINT64
43 __bid64_to_int64_rnint (UINT64 x
44 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
45 _EXC_INFO_PARAM) {
46 #endif
47 SINT64 res;
48 UINT64 x_sign;
49 UINT64 x_exp;
50 int exp; // unbiased exponent
51 // Note: C1 represents x_significand (UINT64)
52 BID_UI64DOUBLE tmp1;
53 unsigned int x_nr_bits;
54 int q, ind, shift;
55 UINT64 C1;
56 UINT128 C;
57 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
58 UINT128 fstar;
59 UINT128 P128;
60
61 // check for NaN or Infinity
62 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
63 // set invalid flag
64 *pfpsf |= INVALID_EXCEPTION;
65 // return Integer Indefinite
66 res = 0x8000000000000000ull;
67 BID_RETURN (res);
68 }
69 // unpack x
70 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
71 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
72 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
73 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
74 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
75 if (C1 > 9999999999999999ull) { // non-canonical
76 x_exp = 0;
77 C1 = 0;
78 }
79 } else {
80 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
81 C1 = x & MASK_BINARY_SIG1;
82 }
83
84 // check for zeros (possibly from non-canonical values)
85 if (C1 == 0x0ull) {
86 // x is 0
87 res = 0x00000000;
88 BID_RETURN (res);
89 }
90 // x is not special and is not zero
91
92 // q = nr. of decimal digits in x (1 <= q <= 54)
93 // determine first the nr. of bits in x
94 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
95 // split the 64-bit value in two 32-bit halves to avoid rounding errors
96 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
97 tmp1.d = (double) (C1 >> 32); // exact conversion
98 x_nr_bits =
99 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
100 } else { // x < 2^32
101 tmp1.d = (double) C1; // exact conversion
102 x_nr_bits =
103 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
104 }
105 } else { // if x < 2^53
106 tmp1.d = (double) C1; // exact conversion
107 x_nr_bits =
108 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
109 }
110 q = __bid_nr_digits[x_nr_bits - 1].digits;
111 if (q == 0) {
112 q = __bid_nr_digits[x_nr_bits - 1].digits1;
113 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
114 q++;
115 }
116 exp = x_exp - 398; // unbiased exponent
117
118 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
119 // set invalid flag
120 *pfpsf |= INVALID_EXCEPTION;
121 // return Integer Indefinite
122 res = 0x8000000000000000ull;
123 BID_RETURN (res);
124 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
125 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
126 // so x rounded to an integer may or may not fit in a signed 64-bit int
127 // the cases that do not fit are identified here; the ones that fit
128 // fall through and will be handled with other cases further,
129 // under '1 <= q + exp <= 19'
130 if (x_sign) { // if n < 0 and q + exp = 19
131 // if n < -2^63 - 1/2 then n is too large
132 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
133 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
134 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
135 // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
136 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
137 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
138 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
139 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
140 // set invalid flag
141 *pfpsf |= INVALID_EXCEPTION;
142 // return Integer Indefinite
143 res = 0x8000000000000000ull;
144 BID_RETURN (res);
145 }
146 // else cases that can be rounded to a 64-bit int fall through
147 // to '1 <= q + exp <= 19'
148 } else { // if n > 0 and q + exp = 19
149 // if n >= 2^63 - 1/2 then n is too large
150 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
151 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
152 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
153 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
154 C.w[1] = 0x0000000000000004ull;
155 C.w[0] = 0xfffffffffffffffbull;
156 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
157 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
158 if (C.w[1] > 0x04ull ||
159 (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
160 // set invalid flag
161 *pfpsf |= INVALID_EXCEPTION;
162 // return Integer Indefinite
163 res = 0x8000000000000000ull;
164 BID_RETURN (res);
165 }
166 // else cases that can be rounded to a 64-bit int fall through
167 // to '1 <= q + exp <= 19'
168 } // end else if n > 0 and q + exp = 19
169 } // end else if ((q + exp) == 19)
170
171 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
172 // Note: some of the cases tested for above fall through to this point
173 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
174 // return 0
175 res = 0x0000000000000000ull;
176 BID_RETURN (res);
177 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
178 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
179 // res = 0
180 // else
181 // res = +/-1
182 ind = q - 1; // 0 <= ind <= 15
183 if (C1 <= __bid_midpoint64[ind]) {
184 res = 0x0000000000000000ull; // return 0
185 } else if (x_sign) { // n < 0
186 res = 0xffffffffffffffffull; // return -1
187 } else { // n > 0
188 res = 0x0000000000000001ull; // return +1
189 }
190 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
191 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
192 // to nearest to a 64-bit signed integer
193 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
194 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
195 // chop off ind digits from the lower part of C1
196 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
197 C1 = C1 + __bid_midpoint64[ind - 1];
198 // calculate C* and f*
199 // C* is actually floor(C*) in this case
200 // C* and f* need shifting and masking, as shown by
201 // __bid_shiftright128[] and __bid_maskhigh128[]
202 // 1 <= x <= 15
203 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
204 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
205 // the approximation of 10^(-x) was rounded up to 54 bits
206 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
207 Cstar = P128.w[1];
208 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
209 fstar.w[0] = P128.w[0];
210 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
211 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
212 // if (0 < f* < 10^(-x)) then the result is a midpoint
213 // if floor(C*) is even then C* = floor(C*) - logical right
214 // shift; C* has p decimal digits, correct by Prop. 1)
215 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
216 // shift; C* has p decimal digits, correct by Pr. 1)
217 // else
218 // C* = floor(C*) (logical right shift; C has p decimal digits,
219 // correct by Property 1)
220 // n = C* * 10^(e+x)
221
222 // shift right C* by Ex-64 = __bid_shiftright128[ind]
223 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
224 Cstar = Cstar >> shift;
225
226 // if the result was a midpoint it was rounded away from zero, so
227 // it will need a correction
228 // check for midpoints
229 if ((fstar.w[1] == 0) && fstar.w[0] &&
230 (fstar.w[0] <= __bid_ten2mk128trunc[ind - 1].w[1])) {
231 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
232 // __bid_ten2mk128[ind -1].w[1]
233 // the result is a midpoint; round to nearest
234 if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
235 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
236 Cstar--; // Cstar is now even
237 } // else MP in [ODD, EVEN]
238 }
239 if (x_sign)
240 res = -Cstar;
241 else
242 res = Cstar;
243 } else if (exp == 0) {
244 // 1 <= q <= 16
245 // res = +/-C (exact)
246 if (x_sign)
247 res = -C1;
248 else
249 res = C1;
250 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
251 // (the upper limit of 20 on q + exp is due to the fact that
252 // +/-C * 10^exp is guaranteed to fit in 64 bits)
253 // res = +/-C * 10^exp (exact)
254 if (x_sign)
255 res = -C1 * __bid_ten2k64[exp];
256 else
257 res = C1 * __bid_ten2k64[exp];
258 }
259 }
260 BID_RETURN (res);
261 }
262
263 /*****************************************************************************
264 * BID64_to_int64_xrnint
265 ****************************************************************************/
266
267 #if DECIMAL_CALL_BY_REFERENCE
268 void
269 __bid64_to_int64_xrnint (SINT64 * pres, UINT64 * px
270 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
271 _EXC_INFO_PARAM) {
272 UINT64 x = *px;
273 #else
274 SINT64
275 __bid64_to_int64_xrnint (UINT64 x
276 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
277 _EXC_INFO_PARAM) {
278 #endif
279 SINT64 res;
280 UINT64 x_sign;
281 UINT64 x_exp;
282 int exp; // unbiased exponent
283 // Note: C1 represents x_significand (UINT64)
284 UINT64 tmp64;
285 BID_UI64DOUBLE tmp1;
286 unsigned int x_nr_bits;
287 int q, ind, shift;
288 UINT64 C1;
289 UINT128 C;
290 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
291 UINT128 fstar;
292 UINT128 P128;
293
294 // check for NaN or Infinity
295 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
296 // set invalid flag
297 *pfpsf |= INVALID_EXCEPTION;
298 // return Integer Indefinite
299 res = 0x8000000000000000ull;
300 BID_RETURN (res);
301 }
302 // unpack x
303 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
304 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
305 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
306 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
307 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
308 if (C1 > 9999999999999999ull) { // non-canonical
309 x_exp = 0;
310 C1 = 0;
311 }
312 } else {
313 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
314 C1 = x & MASK_BINARY_SIG1;
315 }
316
317 // check for zeros (possibly from non-canonical values)
318 if (C1 == 0x0ull) {
319 // x is 0
320 res = 0x00000000;
321 BID_RETURN (res);
322 }
323 // x is not special and is not zero
324
325 // q = nr. of decimal digits in x (1 <= q <= 54)
326 // determine first the nr. of bits in x
327 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
328 // split the 64-bit value in two 32-bit halves to avoid rounding errors
329 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
330 tmp1.d = (double) (C1 >> 32); // exact conversion
331 x_nr_bits =
332 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
333 } else { // x < 2^32
334 tmp1.d = (double) C1; // exact conversion
335 x_nr_bits =
336 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
337 }
338 } else { // if x < 2^53
339 tmp1.d = (double) C1; // exact conversion
340 x_nr_bits =
341 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
342 }
343 q = __bid_nr_digits[x_nr_bits - 1].digits;
344 if (q == 0) {
345 q = __bid_nr_digits[x_nr_bits - 1].digits1;
346 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
347 q++;
348 }
349 exp = x_exp - 398; // unbiased exponent
350
351 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
352 // set invalid flag
353 *pfpsf |= INVALID_EXCEPTION;
354 // return Integer Indefinite
355 res = 0x8000000000000000ull;
356 BID_RETURN (res);
357 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
358 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
359 // so x rounded to an integer may or may not fit in a signed 64-bit int
360 // the cases that do not fit are identified here; the ones that fit
361 // fall through and will be handled with other cases further,
362 // under '1 <= q + exp <= 19'
363 if (x_sign) { // if n < 0 and q + exp = 19
364 // if n < -2^63 - 1/2 then n is too large
365 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
366 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
367 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
368 // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
369 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
370 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
371 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
372 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
373 // set invalid flag
374 *pfpsf |= INVALID_EXCEPTION;
375 // return Integer Indefinite
376 res = 0x8000000000000000ull;
377 BID_RETURN (res);
378 }
379 // else cases that can be rounded to a 64-bit int fall through
380 // to '1 <= q + exp <= 19'
381 } else { // if n > 0 and q + exp = 19
382 // if n >= 2^63 - 1/2 then n is too large
383 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
384 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
385 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
386 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
387 C.w[1] = 0x0000000000000004ull;
388 C.w[0] = 0xfffffffffffffffbull;
389 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
390 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
391 if (C.w[1] > 0x04ull ||
392 (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
393 // set invalid flag
394 *pfpsf |= INVALID_EXCEPTION;
395 // return Integer Indefinite
396 res = 0x8000000000000000ull;
397 BID_RETURN (res);
398 }
399 // else cases that can be rounded to a 64-bit int fall through
400 // to '1 <= q + exp <= 19'
401 } // end else if n > 0 and q + exp = 19
402 } // end else if ((q + exp) == 19)
403
404 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
405 // Note: some of the cases tested for above fall through to this point
406 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
407 // set inexact flag
408 *pfpsf |= INEXACT_EXCEPTION;
409 // return 0
410 res = 0x0000000000000000ull;
411 BID_RETURN (res);
412 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
413 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
414 // res = 0
415 // else
416 // res = +/-1
417 ind = q - 1; // 0 <= ind <= 15
418 if (C1 <= __bid_midpoint64[ind]) {
419 res = 0x0000000000000000ull; // return 0
420 } else if (x_sign) { // n < 0
421 res = 0xffffffffffffffffull; // return -1
422 } else { // n > 0
423 res = 0x0000000000000001ull; // return +1
424 }
425 // set inexact flag
426 *pfpsf |= INEXACT_EXCEPTION;
427 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
428 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
429 // to nearest to a 64-bit signed integer
430 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
431 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
432 // chop off ind digits from the lower part of C1
433 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
434 C1 = C1 + __bid_midpoint64[ind - 1];
435 // calculate C* and f*
436 // C* is actually floor(C*) in this case
437 // C* and f* need shifting and masking, as shown by
438 // __bid_shiftright128[] and __bid_maskhigh128[]
439 // 1 <= x <= 15
440 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
441 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
442 // the approximation of 10^(-x) was rounded up to 54 bits
443 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
444 Cstar = P128.w[1];
445 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
446 fstar.w[0] = P128.w[0];
447 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
448 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
449 // if (0 < f* < 10^(-x)) then the result is a midpoint
450 // if floor(C*) is even then C* = floor(C*) - logical right
451 // shift; C* has p decimal digits, correct by Prop. 1)
452 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
453 // shift; C* has p decimal digits, correct by Pr. 1)
454 // else
455 // C* = floor(C*) (logical right shift; C has p decimal digits,
456 // correct by Property 1)
457 // n = C* * 10^(e+x)
458
459 // shift right C* by Ex-64 = __bid_shiftright128[ind]
460 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
461 Cstar = Cstar >> shift;
462 // determine inexactness of the rounding of C*
463 // if (0 < f* - 1/2 < 10^(-x)) then
464 // the result is exact
465 // else // if (f* - 1/2 > T*) then
466 // the result is inexact
467 if (ind - 1 <= 2) {
468 if (fstar.w[0] > 0x8000000000000000ull) {
469 // f* > 1/2 and the result may be exact
470 tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
471 if ((tmp64 > __bid_ten2mk128trunc[ind - 1].w[1])) {
472 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
473 // __bid_ten2mk128[ind -1].w[1]
474 // set the inexact flag
475 *pfpsf |= INEXACT_EXCEPTION;
476 } // else the result is exact
477 } else { // the result is inexact; f2* <= 1/2
478 // set the inexact flag
479 *pfpsf |= INEXACT_EXCEPTION;
480 }
481 } else { // if 3 <= ind - 1 <= 14
482 if (fstar.w[1] > __bid_one_half128[ind - 1] ||
483 (fstar.w[1] == __bid_one_half128[ind - 1] && fstar.w[0])) {
484 // f2* > 1/2 and the result may be exact
485 // Calculate f2* - 1/2
486 tmp64 = fstar.w[1] - __bid_one_half128[ind - 1];
487 if (tmp64 || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
488 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
489 // __bid_ten2mk128[ind -1].w[1]
490 // set the inexact flag
491 *pfpsf |= INEXACT_EXCEPTION;
492 } // else the result is exact
493 } else { // the result is inexact; f2* <= 1/2
494 // set the inexact flag
495 *pfpsf |= INEXACT_EXCEPTION;
496 }
497 }
498
499 // if the result was a midpoint it was rounded away from zero, so
500 // it will need a correction
501 // check for midpoints
502 if ((fstar.w[1] == 0) && fstar.w[0] &&
503 (fstar.w[0] <= __bid_ten2mk128trunc[ind - 1].w[1])) {
504 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
505 // __bid_ten2mk128[ind -1].w[1]
506 // the result is a midpoint; round to nearest
507 if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
508 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
509 Cstar--; // Cstar is now even
510 } // else MP in [ODD, EVEN]
511 }
512 if (x_sign)
513 res = -Cstar;
514 else
515 res = Cstar;
516 } else if (exp == 0) {
517 // 1 <= q <= 16
518 // res = +/-C (exact)
519 if (x_sign)
520 res = -C1;
521 else
522 res = C1;
523 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
524 // (the upper limit of 20 on q + exp is due to the fact that
525 // +/-C * 10^exp is guaranteed to fit in 64 bits)
526 // res = +/-C * 10^exp (exact)
527 if (x_sign)
528 res = -C1 * __bid_ten2k64[exp];
529 else
530 res = C1 * __bid_ten2k64[exp];
531 }
532 }
533 BID_RETURN (res);
534 }
535
536 /*****************************************************************************
537 * BID64_to_int64_floor
538 ****************************************************************************/
539
540 #if DECIMAL_CALL_BY_REFERENCE
541 void
542 __bid64_to_int64_floor (SINT64 * pres, UINT64 * px
543 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
544 _EXC_INFO_PARAM) {
545 UINT64 x = *px;
546 #else
547 SINT64
548 __bid64_to_int64_floor (UINT64 x
549 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
550 _EXC_INFO_PARAM) {
551 #endif
552 SINT64 res;
553 UINT64 x_sign;
554 UINT64 x_exp;
555 int exp; // unbiased exponent
556 // Note: C1 represents x_significand (UINT64)
557 BID_UI64DOUBLE tmp1;
558 unsigned int x_nr_bits;
559 int q, ind, shift;
560 UINT64 C1;
561 UINT128 C;
562 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
563 UINT128 fstar;
564 UINT128 P128;
565
566 // check for NaN or Infinity
567 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
568 // set invalid flag
569 *pfpsf |= INVALID_EXCEPTION;
570 // return Integer Indefinite
571 res = 0x8000000000000000ull;
572 BID_RETURN (res);
573 }
574 // unpack x
575 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
576 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
577 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
578 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
579 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
580 if (C1 > 9999999999999999ull) { // non-canonical
581 x_exp = 0;
582 C1 = 0;
583 }
584 } else {
585 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
586 C1 = x & MASK_BINARY_SIG1;
587 }
588
589 // check for zeros (possibly from non-canonical values)
590 if (C1 == 0x0ull) {
591 // x is 0
592 res = 0x0000000000000000ull;
593 BID_RETURN (res);
594 }
595 // x is not special and is not zero
596
597 // q = nr. of decimal digits in x (1 <= q <= 54)
598 // determine first the nr. of bits in x
599 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
600 // split the 64-bit value in two 32-bit halves to avoid rounding errors
601 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
602 tmp1.d = (double) (C1 >> 32); // exact conversion
603 x_nr_bits =
604 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
605 } else { // x < 2^32
606 tmp1.d = (double) C1; // exact conversion
607 x_nr_bits =
608 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
609 }
610 } else { // if x < 2^53
611 tmp1.d = (double) C1; // exact conversion
612 x_nr_bits =
613 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
614 }
615 q = __bid_nr_digits[x_nr_bits - 1].digits;
616 if (q == 0) {
617 q = __bid_nr_digits[x_nr_bits - 1].digits1;
618 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
619 q++;
620 }
621 exp = x_exp - 398; // unbiased exponent
622
623 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
624 // set invalid flag
625 *pfpsf |= INVALID_EXCEPTION;
626 // return Integer Indefinite
627 res = 0x8000000000000000ull;
628 BID_RETURN (res);
629 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
630 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
631 // so x rounded to an integer may or may not fit in a signed 64-bit int
632 // the cases that do not fit are identified here; the ones that fit
633 // fall through and will be handled with other cases further,
634 // under '1 <= q + exp <= 19'
635 if (x_sign) { // if n < 0 and q + exp = 19
636 // if n < -2^63 then n is too large
637 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
638 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
639 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
640 // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
641 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
642 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
643 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
644 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
645 // set invalid flag
646 *pfpsf |= INVALID_EXCEPTION;
647 // return Integer Indefinite
648 res = 0x8000000000000000ull;
649 BID_RETURN (res);
650 }
651 // else cases that can be rounded to a 64-bit int fall through
652 // to '1 <= q + exp <= 19'
653 } else { // if n > 0 and q + exp = 19
654 // if n >= 2^63 then n is too large
655 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
656 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
657 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
658 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
659 C.w[1] = 0x0000000000000005ull;
660 C.w[0] = 0x0000000000000000ull;
661 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
662 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
663 if (C.w[1] >= 0x05ull) {
664 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
665 // set invalid flag
666 *pfpsf |= INVALID_EXCEPTION;
667 // return Integer Indefinite
668 res = 0x8000000000000000ull;
669 BID_RETURN (res);
670 }
671 // else cases that can be rounded to a 64-bit int fall through
672 // to '1 <= q + exp <= 19'
673 } // end else if n > 0 and q + exp = 19
674 } // end else if ((q + exp) == 19)
675
676 // n is not too large to be converted to int64: -2^63 <= n < 2^63
677 // Note: some of the cases tested for above fall through to this point
678 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
679 // return -1 or 0
680 if (x_sign)
681 res = 0xffffffffffffffffull;
682 else
683 res = 0x0000000000000000ull;
684 BID_RETURN (res);
685 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
686 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
687 // to nearest to a 64-bit signed integer
688 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
689 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
690 // chop off ind digits from the lower part of C1
691 // C1 fits in 64 bits
692 // calculate C* and f*
693 // C* is actually floor(C*) in this case
694 // C* and f* need shifting and masking, as shown by
695 // __bid_shiftright128[] and __bid_maskhigh128[]
696 // 1 <= x <= 15
697 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
698 // C* = C1 * 10^(-x)
699 // the approximation of 10^(-x) was rounded up to 54 bits
700 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
701 Cstar = P128.w[1];
702 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
703 fstar.w[0] = P128.w[0];
704 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
705 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
706 // C* = floor(C*) (logical right shift; C has p decimal digits,
707 // correct by Property 1)
708 // n = C* * 10^(e+x)
709
710 // shift right C* by Ex-64 = __bid_shiftright128[ind]
711 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
712 Cstar = Cstar >> shift;
713 // determine inexactness of the rounding of C*
714 // if (0 < f* < 10^(-x)) then
715 // the result is exact
716 // else // if (f* > T*) then
717 // the result is inexact
718 if (ind - 1 <= 2) { // fstar.w[1] is 0
719 if (fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
720 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
721 // __bid_ten2mk128[ind -1].w[1]
722 if (x_sign) { // negative and inexact
723 Cstar++;
724 }
725 } // else the result is exact
726 } else { // if 3 <= ind - 1 <= 14
727 if (fstar.w[1] || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
728 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
729 // __bid_ten2mk128[ind -1].w[1]
730 if (x_sign) { // negative and inexact
731 Cstar++;
732 }
733 } // else the result is exact
734 }
735
736 if (x_sign)
737 res = -Cstar;
738 else
739 res = Cstar;
740 } else if (exp == 0) {
741 // 1 <= q <= 16
742 // res = +/-C (exact)
743 if (x_sign)
744 res = -C1;
745 else
746 res = C1;
747 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
748 // (the upper limit of 20 on q + exp is due to the fact that
749 // +/-C * 10^exp is guaranteed to fit in 64 bits)
750 // res = +/-C * 10^exp (exact)
751 if (x_sign)
752 res = -C1 * __bid_ten2k64[exp];
753 else
754 res = C1 * __bid_ten2k64[exp];
755 }
756 }
757 BID_RETURN (res);
758 }
759
760 /*****************************************************************************
761 * BID64_to_int64_xfloor
762 ****************************************************************************/
763
764 #if DECIMAL_CALL_BY_REFERENCE
765 void
766 __bid64_to_int64_xfloor (SINT64 * pres, UINT64 * px
767 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
768 _EXC_INFO_PARAM) {
769 UINT64 x = *px;
770 #else
771 SINT64
772 __bid64_to_int64_xfloor (UINT64 x
773 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
774 _EXC_INFO_PARAM) {
775 #endif
776 SINT64 res;
777 UINT64 x_sign;
778 UINT64 x_exp;
779 int exp; // unbiased exponent
780 // Note: C1 represents x_significand (UINT64)
781 BID_UI64DOUBLE tmp1;
782 unsigned int x_nr_bits;
783 int q, ind, shift;
784 UINT64 C1;
785 UINT128 C;
786 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
787 UINT128 fstar;
788 UINT128 P128;
789
790 // check for NaN or Infinity
791 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
792 // set invalid flag
793 *pfpsf |= INVALID_EXCEPTION;
794 // return Integer Indefinite
795 res = 0x8000000000000000ull;
796 BID_RETURN (res);
797 }
798 // unpack x
799 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
800 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
801 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
802 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
803 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
804 if (C1 > 9999999999999999ull) { // non-canonical
805 x_exp = 0;
806 C1 = 0;
807 }
808 } else {
809 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
810 C1 = x & MASK_BINARY_SIG1;
811 }
812
813 // check for zeros (possibly from non-canonical values)
814 if (C1 == 0x0ull) {
815 // x is 0
816 res = 0x0000000000000000ull;
817 BID_RETURN (res);
818 }
819 // x is not special and is not zero
820
821 // q = nr. of decimal digits in x (1 <= q <= 54)
822 // determine first the nr. of bits in x
823 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
824 // split the 64-bit value in two 32-bit halves to avoid rounding errors
825 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
826 tmp1.d = (double) (C1 >> 32); // exact conversion
827 x_nr_bits =
828 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
829 } else { // x < 2^32
830 tmp1.d = (double) C1; // exact conversion
831 x_nr_bits =
832 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
833 }
834 } else { // if x < 2^53
835 tmp1.d = (double) C1; // exact conversion
836 x_nr_bits =
837 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
838 }
839 q = __bid_nr_digits[x_nr_bits - 1].digits;
840 if (q == 0) {
841 q = __bid_nr_digits[x_nr_bits - 1].digits1;
842 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
843 q++;
844 }
845 exp = x_exp - 398; // unbiased exponent
846
847 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
848 // set invalid flag
849 *pfpsf |= INVALID_EXCEPTION;
850 // return Integer Indefinite
851 res = 0x8000000000000000ull;
852 BID_RETURN (res);
853 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
854 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
855 // so x rounded to an integer may or may not fit in a signed 64-bit int
856 // the cases that do not fit are identified here; the ones that fit
857 // fall through and will be handled with other cases further,
858 // under '1 <= q + exp <= 19'
859 if (x_sign) { // if n < 0 and q + exp = 19
860 // if n < -2^63 then n is too large
861 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
862 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
863 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
864 // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
865 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
866 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
867 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
868 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
869 // set invalid flag
870 *pfpsf |= INVALID_EXCEPTION;
871 // return Integer Indefinite
872 res = 0x8000000000000000ull;
873 BID_RETURN (res);
874 }
875 // else cases that can be rounded to a 64-bit int fall through
876 // to '1 <= q + exp <= 19'
877 } else { // if n > 0 and q + exp = 19
878 // if n >= 2^63 then n is too large
879 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
880 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
881 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
882 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
883 C.w[1] = 0x0000000000000005ull;
884 C.w[0] = 0x0000000000000000ull;
885 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
886 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
887 if (C.w[1] >= 0x05ull) {
888 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
889 // set invalid flag
890 *pfpsf |= INVALID_EXCEPTION;
891 // return Integer Indefinite
892 res = 0x8000000000000000ull;
893 BID_RETURN (res);
894 }
895 // else cases that can be rounded to a 64-bit int fall through
896 // to '1 <= q + exp <= 19'
897 } // end else if n > 0 and q + exp = 19
898 } // end else if ((q + exp) == 19)
899
900 // n is not too large to be converted to int64: -2^63 <= n < 2^63
901 // Note: some of the cases tested for above fall through to this point
902 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
903 // set inexact flag
904 *pfpsf |= INEXACT_EXCEPTION;
905 // return -1 or 0
906 if (x_sign)
907 res = 0xffffffffffffffffull;
908 else
909 res = 0x0000000000000000ull;
910 BID_RETURN (res);
911 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
912 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
913 // to nearest to a 64-bit signed integer
914 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
915 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
916 // chop off ind digits from the lower part of C1
917 // C1 fits in 64 bits
918 // calculate C* and f*
919 // C* is actually floor(C*) in this case
920 // C* and f* need shifting and masking, as shown by
921 // __bid_shiftright128[] and __bid_maskhigh128[]
922 // 1 <= x <= 15
923 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
924 // C* = C1 * 10^(-x)
925 // the approximation of 10^(-x) was rounded up to 54 bits
926 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
927 Cstar = P128.w[1];
928 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
929 fstar.w[0] = P128.w[0];
930 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
931 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
932 // C* = floor(C*) (logical right shift; C has p decimal digits,
933 // correct by Property 1)
934 // n = C* * 10^(e+x)
935
936 // shift right C* by Ex-64 = __bid_shiftright128[ind]
937 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
938 Cstar = Cstar >> shift;
939 // determine inexactness of the rounding of C*
940 // if (0 < f* < 10^(-x)) then
941 // the result is exact
942 // else // if (f* > T*) then
943 // the result is inexact
944 if (ind - 1 <= 2) { // fstar.w[1] is 0
945 if (fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
946 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
947 // __bid_ten2mk128[ind -1].w[1]
948 if (x_sign) { // negative and inexact
949 Cstar++;
950 }
951 // set the inexact flag
952 *pfpsf |= INEXACT_EXCEPTION;
953 } // else the result is exact
954 } else { // if 3 <= ind - 1 <= 14
955 if (fstar.w[1] || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
956 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
957 // __bid_ten2mk128[ind -1].w[1]
958 if (x_sign) { // negative and inexact
959 Cstar++;
960 }
961 // set the inexact flag
962 *pfpsf |= INEXACT_EXCEPTION;
963 } // else the result is exact
964 }
965
966 if (x_sign)
967 res = -Cstar;
968 else
969 res = Cstar;
970 } else if (exp == 0) {
971 // 1 <= q <= 16
972 // res = +/-C (exact)
973 if (x_sign)
974 res = -C1;
975 else
976 res = C1;
977 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
978 // (the upper limit of 20 on q + exp is due to the fact that
979 // +/-C * 10^exp is guaranteed to fit in 64 bits)
980 // res = +/-C * 10^exp (exact)
981 if (x_sign)
982 res = -C1 * __bid_ten2k64[exp];
983 else
984 res = C1 * __bid_ten2k64[exp];
985 }
986 }
987 BID_RETURN (res);
988 }
989
990 /*****************************************************************************
991 * BID64_to_int64_ceil
992 ****************************************************************************/
993
994 #if DECIMAL_CALL_BY_REFERENCE
995 void
996 __bid64_to_int64_ceil (SINT64 * pres, UINT64 * px
997 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
998 {
999 UINT64 x = *px;
1000 #else
1001 SINT64
1002 __bid64_to_int64_ceil (UINT64 x
1003 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
1004 {
1005 #endif
1006 SINT64 res;
1007 UINT64 x_sign;
1008 UINT64 x_exp;
1009 int exp; // unbiased exponent
1010 // Note: C1 represents x_significand (UINT64)
1011 BID_UI64DOUBLE tmp1;
1012 unsigned int x_nr_bits;
1013 int q, ind, shift;
1014 UINT64 C1;
1015 UINT128 C;
1016 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1017 UINT128 fstar;
1018 UINT128 P128;
1019
1020 // check for NaN or Infinity
1021 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
1022 // set invalid flag
1023 *pfpsf |= INVALID_EXCEPTION;
1024 // return Integer Indefinite
1025 res = 0x8000000000000000ull;
1026 BID_RETURN (res);
1027 }
1028 // unpack x
1029 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1030 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1031 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1032 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
1033 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1034 if (C1 > 9999999999999999ull) { // non-canonical
1035 x_exp = 0;
1036 C1 = 0;
1037 }
1038 } else {
1039 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
1040 C1 = x & MASK_BINARY_SIG1;
1041 }
1042
1043 // check for zeros (possibly from non-canonical values)
1044 if (C1 == 0x0ull) {
1045 // x is 0
1046 res = 0x00000000;
1047 BID_RETURN (res);
1048 }
1049 // x is not special and is not zero
1050
1051 // q = nr. of decimal digits in x (1 <= q <= 54)
1052 // determine first the nr. of bits in x
1053 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1054 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1055 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
1056 tmp1.d = (double) (C1 >> 32); // exact conversion
1057 x_nr_bits =
1058 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1059 } else { // x < 2^32
1060 tmp1.d = (double) C1; // exact conversion
1061 x_nr_bits =
1062 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1063 }
1064 } else { // if x < 2^53
1065 tmp1.d = (double) C1; // exact conversion
1066 x_nr_bits =
1067 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1068 }
1069 q = __bid_nr_digits[x_nr_bits - 1].digits;
1070 if (q == 0) {
1071 q = __bid_nr_digits[x_nr_bits - 1].digits1;
1072 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
1073 q++;
1074 }
1075 exp = x_exp - 398; // unbiased exponent
1076
1077 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1078 // set invalid flag
1079 *pfpsf |= INVALID_EXCEPTION;
1080 // return Integer Indefinite
1081 res = 0x8000000000000000ull;
1082 BID_RETURN (res);
1083 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1084 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1085 // so x rounded to an integer may or may not fit in a signed 64-bit int
1086 // the cases that do not fit are identified here; the ones that fit
1087 // fall through and will be handled with other cases further,
1088 // under '1 <= q + exp <= 19'
1089 if (x_sign) { // if n < 0 and q + exp = 19
1090 // if n <= -2^63 - 1 then n is too large
1091 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1092 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1093 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1094 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1095 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1096 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1097 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1098 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1099 // set invalid flag
1100 *pfpsf |= INVALID_EXCEPTION;
1101 // return Integer Indefinite
1102 res = 0x8000000000000000ull;
1103 BID_RETURN (res);
1104 }
1105 // else cases that can be rounded to a 64-bit int fall through
1106 // to '1 <= q + exp <= 19'
1107 } else { // if n > 0 and q + exp = 19
1108 // if n > 2^63 - 1 then n is too large
1109 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1110 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
1111 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
1112 // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
1113 C.w[1] = 0x0000000000000004ull;
1114 C.w[0] = 0xfffffffffffffff6ull;
1115 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1116 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1117 if (C.w[1] > 0x04ull ||
1118 (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
1119 // set invalid flag
1120 *pfpsf |= INVALID_EXCEPTION;
1121 // return Integer Indefinite
1122 res = 0x8000000000000000ull;
1123 BID_RETURN (res);
1124 }
1125 // else cases that can be rounded to a 64-bit int fall through
1126 // to '1 <= q + exp <= 19'
1127 } // end else if n > 0 and q + exp = 19
1128 } // end else if ((q + exp) == 19)
1129
1130 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1131 // Note: some of the cases tested for above fall through to this point
1132 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1133 // return 0 or 1
1134 if (x_sign)
1135 res = 0x00000000;
1136 else
1137 res = 0x00000001;
1138 BID_RETURN (res);
1139 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1140 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1141 // to nearest to a 64-bit signed integer
1142 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1143 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
1144 // chop off ind digits from the lower part of C1
1145 // C1 fits in 64 bits
1146 // calculate C* and f*
1147 // C* is actually floor(C*) in this case
1148 // C* and f* need shifting and masking, as shown by
1149 // __bid_shiftright128[] and __bid_maskhigh128[]
1150 // 1 <= x <= 15
1151 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1152 // C* = C1 * 10^(-x)
1153 // the approximation of 10^(-x) was rounded up to 54 bits
1154 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
1155 Cstar = P128.w[1];
1156 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
1157 fstar.w[0] = P128.w[0];
1158 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
1159 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1160 // C* = floor(C*) (logical right shift; C has p decimal digits,
1161 // correct by Property 1)
1162 // n = C* * 10^(e+x)
1163
1164 // shift right C* by Ex-64 = __bid_shiftright128[ind]
1165 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1166 Cstar = Cstar >> shift;
1167 // determine inexactness of the rounding of C*
1168 // if (0 < f* < 10^(-x)) then
1169 // the result is exact
1170 // else // if (f* > T*) then
1171 // the result is inexact
1172 if (ind - 1 <= 2) { // fstar.w[1] is 0
1173 if (fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1174 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1175 // __bid_ten2mk128[ind -1].w[1]
1176 if (!x_sign) { // positive and inexact
1177 Cstar++;
1178 }
1179 } // else the result is exact
1180 } else { // if 3 <= ind - 1 <= 14
1181 if (fstar.w[1] || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1182 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1183 // __bid_ten2mk128[ind -1].w[1]
1184 if (!x_sign) { // positive and inexact
1185 Cstar++;
1186 }
1187 } // else the result is exact
1188 }
1189
1190 if (x_sign)
1191 res = -Cstar;
1192 else
1193 res = Cstar;
1194 } else if (exp == 0) {
1195 // 1 <= q <= 16
1196 // res = +/-C (exact)
1197 if (x_sign)
1198 res = -C1;
1199 else
1200 res = C1;
1201 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1202 // (the upper limit of 20 on q + exp is due to the fact that
1203 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1204 // res = +/-C * 10^exp (exact)
1205 if (x_sign)
1206 res = -C1 * __bid_ten2k64[exp];
1207 else
1208 res = C1 * __bid_ten2k64[exp];
1209 }
1210 }
1211 BID_RETURN (res);
1212 }
1213
1214 /*****************************************************************************
1215 * BID64_to_int64_xceil
1216 ****************************************************************************/
1217
1218 #if DECIMAL_CALL_BY_REFERENCE
1219 void
1220 __bid64_to_int64_xceil (SINT64 * pres, UINT64 * px
1221 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1222 _EXC_INFO_PARAM) {
1223 UINT64 x = *px;
1224 #else
1225 SINT64
1226 __bid64_to_int64_xceil (UINT64 x
1227 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1228 _EXC_INFO_PARAM) {
1229 #endif
1230 SINT64 res;
1231 UINT64 x_sign;
1232 UINT64 x_exp;
1233 int exp; // unbiased exponent
1234 // Note: C1 represents x_significand (UINT64)
1235 BID_UI64DOUBLE tmp1;
1236 unsigned int x_nr_bits;
1237 int q, ind, shift;
1238 UINT64 C1;
1239 UINT128 C;
1240 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1241 UINT128 fstar;
1242 UINT128 P128;
1243
1244 // check for NaN or Infinity
1245 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
1246 // set invalid flag
1247 *pfpsf |= INVALID_EXCEPTION;
1248 // return Integer Indefinite
1249 res = 0x8000000000000000ull;
1250 BID_RETURN (res);
1251 }
1252 // unpack x
1253 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1254 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1255 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1256 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
1257 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1258 if (C1 > 9999999999999999ull) { // non-canonical
1259 x_exp = 0;
1260 C1 = 0;
1261 }
1262 } else {
1263 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
1264 C1 = x & MASK_BINARY_SIG1;
1265 }
1266
1267 // check for zeros (possibly from non-canonical values)
1268 if (C1 == 0x0ull) {
1269 // x is 0
1270 res = 0x00000000;
1271 BID_RETURN (res);
1272 }
1273 // x is not special and is not zero
1274
1275 // q = nr. of decimal digits in x (1 <= q <= 54)
1276 // determine first the nr. of bits in x
1277 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1278 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1279 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
1280 tmp1.d = (double) (C1 >> 32); // exact conversion
1281 x_nr_bits =
1282 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1283 } else { // x < 2^32
1284 tmp1.d = (double) C1; // exact conversion
1285 x_nr_bits =
1286 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1287 }
1288 } else { // if x < 2^53
1289 tmp1.d = (double) C1; // exact conversion
1290 x_nr_bits =
1291 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1292 }
1293 q = __bid_nr_digits[x_nr_bits - 1].digits;
1294 if (q == 0) {
1295 q = __bid_nr_digits[x_nr_bits - 1].digits1;
1296 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
1297 q++;
1298 }
1299 exp = x_exp - 398; // unbiased exponent
1300
1301 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1302 // set invalid flag
1303 *pfpsf |= INVALID_EXCEPTION;
1304 // return Integer Indefinite
1305 res = 0x8000000000000000ull;
1306 BID_RETURN (res);
1307 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1308 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1309 // so x rounded to an integer may or may not fit in a signed 64-bit int
1310 // the cases that do not fit are identified here; the ones that fit
1311 // fall through and will be handled with other cases further,
1312 // under '1 <= q + exp <= 19'
1313 if (x_sign) { // if n < 0 and q + exp = 19
1314 // if n <= -2^63 - 1 then n is too large
1315 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1316 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1317 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1318 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1319 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1320 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1321 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1322 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1323 // set invalid flag
1324 *pfpsf |= INVALID_EXCEPTION;
1325 // return Integer Indefinite
1326 res = 0x8000000000000000ull;
1327 BID_RETURN (res);
1328 }
1329 // else cases that can be rounded to a 64-bit int fall through
1330 // to '1 <= q + exp <= 19'
1331 } else { // if n > 0 and q + exp = 19
1332 // if n > 2^63 - 1 then n is too large
1333 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
1334 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
1335 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
1336 // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
1337 C.w[1] = 0x0000000000000004ull;
1338 C.w[0] = 0xfffffffffffffff6ull;
1339 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1340 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1341 if (C.w[1] > 0x04ull ||
1342 (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
1343 // set invalid flag
1344 *pfpsf |= INVALID_EXCEPTION;
1345 // return Integer Indefinite
1346 res = 0x8000000000000000ull;
1347 BID_RETURN (res);
1348 }
1349 // else cases that can be rounded to a 64-bit int fall through
1350 // to '1 <= q + exp <= 19'
1351 } // end else if n > 0 and q + exp = 19
1352 } // end else if ((q + exp) == 19)
1353
1354 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1355 // Note: some of the cases tested for above fall through to this point
1356 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1357 // set inexact flag
1358 *pfpsf |= INEXACT_EXCEPTION;
1359 // return 0 or 1
1360 if (x_sign)
1361 res = 0x00000000;
1362 else
1363 res = 0x00000001;
1364 BID_RETURN (res);
1365 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1366 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
1367 // to nearest to a 64-bit signed integer
1368 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1369 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
1370 // chop off ind digits from the lower part of C1
1371 // C1 fits in 64 bits
1372 // calculate C* and f*
1373 // C* is actually floor(C*) in this case
1374 // C* and f* need shifting and masking, as shown by
1375 // __bid_shiftright128[] and __bid_maskhigh128[]
1376 // 1 <= x <= 15
1377 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1378 // C* = C1 * 10^(-x)
1379 // the approximation of 10^(-x) was rounded up to 54 bits
1380 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
1381 Cstar = P128.w[1];
1382 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
1383 fstar.w[0] = P128.w[0];
1384 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
1385 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1386 // C* = floor(C*) (logical right shift; C has p decimal digits,
1387 // correct by Property 1)
1388 // n = C* * 10^(e+x)
1389
1390 // shift right C* by Ex-64 = __bid_shiftright128[ind]
1391 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1392 Cstar = Cstar >> shift;
1393 // determine inexactness of the rounding of C*
1394 // if (0 < f* < 10^(-x)) then
1395 // the result is exact
1396 // else // if (f* > T*) then
1397 // the result is inexact
1398 if (ind - 1 <= 2) { // fstar.w[1] is 0
1399 if (fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1400 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1401 // __bid_ten2mk128[ind -1].w[1]
1402 if (!x_sign) { // positive and inexact
1403 Cstar++;
1404 }
1405 // set the inexact flag
1406 *pfpsf |= INEXACT_EXCEPTION;
1407 } // else the result is exact
1408 } else { // if 3 <= ind - 1 <= 14
1409 if (fstar.w[1] || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1410 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1411 // __bid_ten2mk128[ind -1].w[1]
1412 if (!x_sign) { // positive and inexact
1413 Cstar++;
1414 }
1415 // set the inexact flag
1416 *pfpsf |= INEXACT_EXCEPTION;
1417 } // else the result is exact
1418 }
1419
1420 if (x_sign)
1421 res = -Cstar;
1422 else
1423 res = Cstar;
1424 } else if (exp == 0) {
1425 // 1 <= q <= 16
1426 // res = +/-C (exact)
1427 if (x_sign)
1428 res = -C1;
1429 else
1430 res = C1;
1431 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1432 // (the upper limit of 20 on q + exp is due to the fact that
1433 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1434 // res = +/-C * 10^exp (exact)
1435 if (x_sign)
1436 res = -C1 * __bid_ten2k64[exp];
1437 else
1438 res = C1 * __bid_ten2k64[exp];
1439 }
1440 }
1441 BID_RETURN (res);
1442 }
1443
1444 /*****************************************************************************
1445 * BID64_to_int64_int
1446 ****************************************************************************/
1447
1448 #if DECIMAL_CALL_BY_REFERENCE
1449 void
1450 __bid64_to_int64_int (SINT64 * pres, UINT64 * px
1451 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1452 UINT64 x = *px;
1453 #else
1454 SINT64
1455 __bid64_to_int64_int (UINT64 x
1456 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1457 #endif
1458 SINT64 res;
1459 UINT64 x_sign;
1460 UINT64 x_exp;
1461 int exp; // unbiased exponent
1462 // Note: C1 represents x_significand (UINT64)
1463 BID_UI64DOUBLE tmp1;
1464 unsigned int x_nr_bits;
1465 int q, ind, shift;
1466 UINT64 C1;
1467 UINT128 C;
1468 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1469 UINT128 P128;
1470
1471 // check for NaN or Infinity
1472 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
1473 // set invalid flag
1474 *pfpsf |= INVALID_EXCEPTION;
1475 // return Integer Indefinite
1476 res = 0x8000000000000000ull;
1477 BID_RETURN (res);
1478 }
1479 // unpack x
1480 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1481 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1482 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1483 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
1484 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1485 if (C1 > 9999999999999999ull) { // non-canonical
1486 x_exp = 0;
1487 C1 = 0;
1488 }
1489 } else {
1490 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
1491 C1 = x & MASK_BINARY_SIG1;
1492 }
1493
1494 // check for zeros (possibly from non-canonical values)
1495 if (C1 == 0x0ull) {
1496 // x is 0
1497 res = 0x00000000;
1498 BID_RETURN (res);
1499 }
1500 // x is not special and is not zero
1501
1502 // q = nr. of decimal digits in x (1 <= q <= 54)
1503 // determine first the nr. of bits in x
1504 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1505 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1506 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
1507 tmp1.d = (double) (C1 >> 32); // exact conversion
1508 x_nr_bits =
1509 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1510 } else { // x < 2^32
1511 tmp1.d = (double) C1; // exact conversion
1512 x_nr_bits =
1513 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1514 }
1515 } else { // if x < 2^53
1516 tmp1.d = (double) C1; // exact conversion
1517 x_nr_bits =
1518 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1519 }
1520 q = __bid_nr_digits[x_nr_bits - 1].digits;
1521 if (q == 0) {
1522 q = __bid_nr_digits[x_nr_bits - 1].digits1;
1523 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
1524 q++;
1525 }
1526 exp = x_exp - 398; // unbiased exponent
1527
1528 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1529 // set invalid flag
1530 *pfpsf |= INVALID_EXCEPTION;
1531 // return Integer Indefinite
1532 res = 0x8000000000000000ull;
1533 BID_RETURN (res);
1534 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1535 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1536 // so x rounded to an integer may or may not fit in a signed 64-bit int
1537 // the cases that do not fit are identified here; the ones that fit
1538 // fall through and will be handled with other cases further,
1539 // under '1 <= q + exp <= 19'
1540 if (x_sign) { // if n < 0 and q + exp = 19
1541 // if n <= -2^63 - 1 then n is too large
1542 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1543 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1544 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1545 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1546 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1547 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1548 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1549 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1550 // set invalid flag
1551 *pfpsf |= INVALID_EXCEPTION;
1552 // return Integer Indefinite
1553 res = 0x8000000000000000ull;
1554 BID_RETURN (res);
1555 }
1556 // else cases that can be rounded to a 64-bit int fall through
1557 // to '1 <= q + exp <= 19'
1558 } else { // if n > 0 and q + exp = 19
1559 // if n >= 2^63 then n is too large
1560 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1561 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
1562 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
1563 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
1564 C.w[1] = 0x0000000000000005ull;
1565 C.w[0] = 0x0000000000000000ull;
1566 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1567 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1568 if (C.w[1] >= 0x05ull) {
1569 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1570 // set invalid flag
1571 *pfpsf |= INVALID_EXCEPTION;
1572 // return Integer Indefinite
1573 res = 0x8000000000000000ull;
1574 BID_RETURN (res);
1575 }
1576 // else cases that can be rounded to a 64-bit int fall through
1577 // to '1 <= q + exp <= 19'
1578 } // end else if n > 0 and q + exp = 19
1579 } // end else if ((q + exp) == 19)
1580
1581 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1582 // Note: some of the cases tested for above fall through to this point
1583 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1584 // return 0
1585 res = 0x0000000000000000ull;
1586 BID_RETURN (res);
1587 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1588 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1589 // to nearest to a 64-bit signed integer
1590 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1591 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
1592 // chop off ind digits from the lower part of C1
1593 // C1 fits in 64 bits
1594 // calculate C* and f*
1595 // C* is actually floor(C*) in this case
1596 // C* and f* need shifting and masking, as shown by
1597 // __bid_shiftright128[] and __bid_maskhigh128[]
1598 // 1 <= x <= 15
1599 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1600 // C* = C1 * 10^(-x)
1601 // the approximation of 10^(-x) was rounded up to 54 bits
1602 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
1603 Cstar = P128.w[1];
1604 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
1605 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1606 // C* = floor(C*) (logical right shift; C has p decimal digits,
1607 // correct by Property 1)
1608 // n = C* * 10^(e+x)
1609
1610 // shift right C* by Ex-64 = __bid_shiftright128[ind]
1611 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1612 Cstar = Cstar >> shift;
1613
1614 if (x_sign)
1615 res = -Cstar;
1616 else
1617 res = Cstar;
1618 } else if (exp == 0) {
1619 // 1 <= q <= 16
1620 // res = +/-C (exact)
1621 if (x_sign)
1622 res = -C1;
1623 else
1624 res = C1;
1625 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1626 // (the upper limit of 20 on q + exp is due to the fact that
1627 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1628 // res = +/-C * 10^exp (exact)
1629 if (x_sign)
1630 res = -C1 * __bid_ten2k64[exp];
1631 else
1632 res = C1 * __bid_ten2k64[exp];
1633 }
1634 }
1635 BID_RETURN (res);
1636 }
1637
1638 /*****************************************************************************
1639 * BID64_to_int64_xint
1640 ****************************************************************************/
1641
1642 #if DECIMAL_CALL_BY_REFERENCE
1643 void
1644 __bid64_to_int64_xint (SINT64 * pres, UINT64 * px
1645 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
1646 {
1647 UINT64 x = *px;
1648 #else
1649 SINT64
1650 __bid64_to_int64_xint (UINT64 x
1651 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
1652 {
1653 #endif
1654 SINT64 res;
1655 UINT64 x_sign;
1656 UINT64 x_exp;
1657 int exp; // unbiased exponent
1658 // Note: C1 represents x_significand (UINT64)
1659 BID_UI64DOUBLE tmp1;
1660 unsigned int x_nr_bits;
1661 int q, ind, shift;
1662 UINT64 C1;
1663 UINT128 C;
1664 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1665 UINT128 fstar;
1666 UINT128 P128;
1667
1668 // check for NaN or Infinity
1669 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
1670 // set invalid flag
1671 *pfpsf |= INVALID_EXCEPTION;
1672 // return Integer Indefinite
1673 res = 0x8000000000000000ull;
1674 BID_RETURN (res);
1675 }
1676 // unpack x
1677 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1678 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1679 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1680 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
1681 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1682 if (C1 > 9999999999999999ull) { // non-canonical
1683 x_exp = 0;
1684 C1 = 0;
1685 }
1686 } else {
1687 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
1688 C1 = x & MASK_BINARY_SIG1;
1689 }
1690
1691 // check for zeros (possibly from non-canonical values)
1692 if (C1 == 0x0ull) {
1693 // x is 0
1694 res = 0x00000000;
1695 BID_RETURN (res);
1696 }
1697 // x is not special and is not zero
1698
1699 // q = nr. of decimal digits in x (1 <= q <= 54)
1700 // determine first the nr. of bits in x
1701 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1702 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1703 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
1704 tmp1.d = (double) (C1 >> 32); // exact conversion
1705 x_nr_bits =
1706 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1707 } else { // x < 2^32
1708 tmp1.d = (double) C1; // exact conversion
1709 x_nr_bits =
1710 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1711 }
1712 } else { // if x < 2^53
1713 tmp1.d = (double) C1; // exact conversion
1714 x_nr_bits =
1715 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1716 }
1717 q = __bid_nr_digits[x_nr_bits - 1].digits;
1718 if (q == 0) {
1719 q = __bid_nr_digits[x_nr_bits - 1].digits1;
1720 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
1721 q++;
1722 }
1723 exp = x_exp - 398; // unbiased exponent
1724
1725 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1726 // set invalid flag
1727 *pfpsf |= INVALID_EXCEPTION;
1728 // return Integer Indefinite
1729 res = 0x8000000000000000ull;
1730 BID_RETURN (res);
1731 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1732 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1733 // so x rounded to an integer may or may not fit in a signed 64-bit int
1734 // the cases that do not fit are identified here; the ones that fit
1735 // fall through and will be handled with other cases further,
1736 // under '1 <= q + exp <= 19'
1737 if (x_sign) { // if n < 0 and q + exp = 19
1738 // if n <= -2^63 - 1 then n is too large
1739 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
1740 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
1741 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
1742 // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
1743 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1744 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1745 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
1746 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
1747 // set invalid flag
1748 *pfpsf |= INVALID_EXCEPTION;
1749 // return Integer Indefinite
1750 res = 0x8000000000000000ull;
1751 BID_RETURN (res);
1752 }
1753 // else cases that can be rounded to a 64-bit int fall through
1754 // to '1 <= q + exp <= 19'
1755 } else { // if n > 0 and q + exp = 19
1756 // if n >= 2^63 then n is too large
1757 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
1758 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
1759 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
1760 // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
1761 C.w[1] = 0x0000000000000005ull;
1762 C.w[0] = 0x0000000000000000ull;
1763 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1764 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1765 if (C.w[1] >= 0x05ull) {
1766 // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
1767 // set invalid flag
1768 *pfpsf |= INVALID_EXCEPTION;
1769 // return Integer Indefinite
1770 res = 0x8000000000000000ull;
1771 BID_RETURN (res);
1772 }
1773 // else cases that can be rounded to a 64-bit int fall through
1774 // to '1 <= q + exp <= 19'
1775 } // end else if n > 0 and q + exp = 19
1776 } // end else if ((q + exp) == 19)
1777
1778 // n is not too large to be converted to int64: -2^63-1 < n < 2^63
1779 // Note: some of the cases tested for above fall through to this point
1780 if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
1781 // set inexact flag
1782 *pfpsf |= INEXACT_EXCEPTION;
1783 // return 0
1784 res = 0x0000000000000000ull;
1785 BID_RETURN (res);
1786 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
1787 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
1788 // to nearest to a 64-bit signed integer
1789 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
1790 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
1791 // chop off ind digits from the lower part of C1
1792 // C1 fits in 64 bits
1793 // calculate C* and f*
1794 // C* is actually floor(C*) in this case
1795 // C* and f* need shifting and masking, as shown by
1796 // __bid_shiftright128[] and __bid_maskhigh128[]
1797 // 1 <= x <= 15
1798 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
1799 // C* = C1 * 10^(-x)
1800 // the approximation of 10^(-x) was rounded up to 54 bits
1801 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
1802 Cstar = P128.w[1];
1803 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
1804 fstar.w[0] = P128.w[0];
1805 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
1806 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
1807 // C* = floor(C*) (logical right shift; C has p decimal digits,
1808 // correct by Property 1)
1809 // n = C* * 10^(e+x)
1810
1811 // shift right C* by Ex-64 = __bid_shiftright128[ind]
1812 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
1813 Cstar = Cstar >> shift;
1814 // determine inexactness of the rounding of C*
1815 // if (0 < f* < 10^(-x)) then
1816 // the result is exact
1817 // else // if (f* > T*) then
1818 // the result is inexact
1819 if (ind - 1 <= 2) { // fstar.w[1] is 0
1820 if (fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1821 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1822 // __bid_ten2mk128[ind -1].w[1]
1823 // set the inexact flag
1824 *pfpsf |= INEXACT_EXCEPTION;
1825 } // else the result is exact
1826 } else { // if 3 <= ind - 1 <= 14
1827 if (fstar.w[1] || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
1828 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
1829 // __bid_ten2mk128[ind -1].w[1]
1830 // set the inexact flag
1831 *pfpsf |= INEXACT_EXCEPTION;
1832 } // else the result is exact
1833 }
1834 if (x_sign)
1835 res = -Cstar;
1836 else
1837 res = Cstar;
1838 } else if (exp == 0) {
1839 // 1 <= q <= 16
1840 // res = +/-C (exact)
1841 if (x_sign)
1842 res = -C1;
1843 else
1844 res = C1;
1845 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
1846 // (the upper limit of 20 on q + exp is due to the fact that
1847 // +/-C * 10^exp is guaranteed to fit in 64 bits)
1848 // res = +/-C * 10^exp (exact)
1849 if (x_sign)
1850 res = -C1 * __bid_ten2k64[exp];
1851 else
1852 res = C1 * __bid_ten2k64[exp];
1853 }
1854 }
1855 BID_RETURN (res);
1856 }
1857
1858 /*****************************************************************************
1859 * BID64_to_int64_rninta
1860 ****************************************************************************/
1861
1862 #if DECIMAL_CALL_BY_REFERENCE
1863 void
1864 __bid64_to_int64_rninta (SINT64 * pres, UINT64 * px
1865 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1866 _EXC_INFO_PARAM) {
1867 UINT64 x = *px;
1868 #else
1869 SINT64
1870 __bid64_to_int64_rninta (UINT64 x
1871 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
1872 _EXC_INFO_PARAM) {
1873 #endif
1874 SINT64 res;
1875 UINT64 x_sign;
1876 UINT64 x_exp;
1877 int exp; // unbiased exponent
1878 // Note: C1 represents x_significand (UINT64)
1879 BID_UI64DOUBLE tmp1;
1880 unsigned int x_nr_bits;
1881 int q, ind, shift;
1882 UINT64 C1;
1883 UINT128 C;
1884 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
1885 UINT128 P128;
1886
1887 // check for NaN or Infinity
1888 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
1889 // set invalid flag
1890 *pfpsf |= INVALID_EXCEPTION;
1891 // return Integer Indefinite
1892 res = 0x8000000000000000ull;
1893 BID_RETURN (res);
1894 }
1895 // unpack x
1896 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
1897 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
1898 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
1899 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
1900 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
1901 if (C1 > 9999999999999999ull) { // non-canonical
1902 x_exp = 0;
1903 C1 = 0;
1904 }
1905 } else {
1906 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
1907 C1 = x & MASK_BINARY_SIG1;
1908 }
1909
1910 // check for zeros (possibly from non-canonical values)
1911 if (C1 == 0x0ull) {
1912 // x is 0
1913 res = 0x00000000;
1914 BID_RETURN (res);
1915 }
1916 // x is not special and is not zero
1917
1918 // q = nr. of decimal digits in x (1 <= q <= 54)
1919 // determine first the nr. of bits in x
1920 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
1921 // split the 64-bit value in two 32-bit halves to avoid rounding errors
1922 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
1923 tmp1.d = (double) (C1 >> 32); // exact conversion
1924 x_nr_bits =
1925 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1926 } else { // x < 2^32
1927 tmp1.d = (double) C1; // exact conversion
1928 x_nr_bits =
1929 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1930 }
1931 } else { // if x < 2^53
1932 tmp1.d = (double) C1; // exact conversion
1933 x_nr_bits =
1934 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
1935 }
1936 q = __bid_nr_digits[x_nr_bits - 1].digits;
1937 if (q == 0) {
1938 q = __bid_nr_digits[x_nr_bits - 1].digits1;
1939 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
1940 q++;
1941 }
1942 exp = x_exp - 398; // unbiased exponent
1943
1944 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
1945 // set invalid flag
1946 *pfpsf |= INVALID_EXCEPTION;
1947 // return Integer Indefinite
1948 res = 0x8000000000000000ull;
1949 BID_RETURN (res);
1950 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
1951 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
1952 // so x rounded to an integer may or may not fit in a signed 64-bit int
1953 // the cases that do not fit are identified here; the ones that fit
1954 // fall through and will be handled with other cases further,
1955 // under '1 <= q + exp <= 19'
1956 if (x_sign) { // if n < 0 and q + exp = 19
1957 // if n <= -2^63 - 1/2 then n is too large
1958 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
1959 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
1960 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
1961 // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
1962 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1963 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1964 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
1965 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
1966 // set invalid flag
1967 *pfpsf |= INVALID_EXCEPTION;
1968 // return Integer Indefinite
1969 res = 0x8000000000000000ull;
1970 BID_RETURN (res);
1971 }
1972 // else cases that can be rounded to a 64-bit int fall through
1973 // to '1 <= q + exp <= 19'
1974 } else { // if n > 0 and q + exp = 19
1975 // if n >= 2^63 - 1/2 then n is too large
1976 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
1977 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
1978 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
1979 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
1980 C.w[1] = 0x0000000000000004ull;
1981 C.w[0] = 0xfffffffffffffffbull;
1982 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
1983 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
1984 if (C.w[1] > 0x04ull ||
1985 (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
1986 // set invalid flag
1987 *pfpsf |= INVALID_EXCEPTION;
1988 // return Integer Indefinite
1989 res = 0x8000000000000000ull;
1990 BID_RETURN (res);
1991 }
1992 // else cases that can be rounded to a 64-bit int fall through
1993 // to '1 <= q + exp <= 19'
1994 } // end else if n > 0 and q + exp = 19
1995 } // end else if ((q + exp) == 19)
1996
1997 // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
1998 // Note: some of the cases tested for above fall through to this point
1999 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2000 // return 0
2001 res = 0x0000000000000000ull;
2002 BID_RETURN (res);
2003 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2004 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
2005 // res = 0
2006 // else
2007 // res = +/-1
2008 ind = q - 1; // 0 <= ind <= 15
2009 if (C1 < __bid_midpoint64[ind]) {
2010 res = 0x0000000000000000ull; // return 0
2011 } else if (x_sign) { // n < 0
2012 res = 0xffffffffffffffffull; // return -1
2013 } else { // n > 0
2014 res = 0x0000000000000001ull; // return +1
2015 }
2016 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
2017 // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2018 // to nearest to a 64-bit signed integer
2019 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
2020 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
2021 // chop off ind digits from the lower part of C1
2022 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
2023 C1 = C1 + __bid_midpoint64[ind - 1];
2024 // calculate C* and f*
2025 // C* is actually floor(C*) in this case
2026 // C* and f* need shifting and masking, as shown by
2027 // __bid_shiftright128[] and __bid_maskhigh128[]
2028 // 1 <= x <= 15
2029 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
2030 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2031 // the approximation of 10^(-x) was rounded up to 54 bits
2032 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
2033 Cstar = P128.w[1];
2034 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
2035 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
2036 // if (0 < f* < 10^(-x)) then the result is a midpoint
2037 // if floor(C*) is even then C* = floor(C*) - logical right
2038 // shift; C* has p decimal digits, correct by Prop. 1)
2039 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2040 // shift; C* has p decimal digits, correct by Pr. 1)
2041 // else
2042 // C* = floor(C*) (logical right shift; C has p decimal digits,
2043 // correct by Property 1)
2044 // n = C* * 10^(e+x)
2045
2046 // shift right C* by Ex-64 = __bid_shiftright128[ind]
2047 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
2048 Cstar = Cstar >> shift;
2049
2050 // if the result was a midpoint it was rounded away from zero
2051 if (x_sign)
2052 res = -Cstar;
2053 else
2054 res = Cstar;
2055 } else if (exp == 0) {
2056 // 1 <= q <= 16
2057 // res = +/-C (exact)
2058 if (x_sign)
2059 res = -C1;
2060 else
2061 res = C1;
2062 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
2063 // (the upper limit of 20 on q + exp is due to the fact that
2064 // +/-C * 10^exp is guaranteed to fit in 64 bits)
2065 // res = +/-C * 10^exp (exact)
2066 if (x_sign)
2067 res = -C1 * __bid_ten2k64[exp];
2068 else
2069 res = C1 * __bid_ten2k64[exp];
2070 }
2071 }
2072 BID_RETURN (res);
2073 }
2074
2075 /*****************************************************************************
2076 * BID64_to_int64_xrninta
2077 ****************************************************************************/
2078
2079 #if DECIMAL_CALL_BY_REFERENCE
2080 void
2081 __bid64_to_int64_xrninta (SINT64 * pres, UINT64 * px
2082 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2083 _EXC_INFO_PARAM) {
2084 UINT64 x = *px;
2085 #else
2086 SINT64
2087 __bid64_to_int64_xrninta (UINT64 x
2088 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2089 _EXC_INFO_PARAM) {
2090 #endif
2091 SINT64 res;
2092 UINT64 x_sign;
2093 UINT64 x_exp;
2094 int exp; // unbiased exponent
2095 // Note: C1 represents x_significand (UINT64)
2096 UINT64 tmp64;
2097 BID_UI64DOUBLE tmp1;
2098 unsigned int x_nr_bits;
2099 int q, ind, shift;
2100 UINT64 C1;
2101 UINT128 C;
2102 UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
2103 UINT128 fstar;
2104 UINT128 P128;
2105
2106 // check for NaN or Infinity
2107 if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
2108 // set invalid flag
2109 *pfpsf |= INVALID_EXCEPTION;
2110 // return Integer Indefinite
2111 res = 0x8000000000000000ull;
2112 BID_RETURN (res);
2113 }
2114 // unpack x
2115 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
2116 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
2117 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
2118 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
2119 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
2120 if (C1 > 9999999999999999ull) { // non-canonical
2121 x_exp = 0;
2122 C1 = 0;
2123 }
2124 } else {
2125 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
2126 C1 = x & MASK_BINARY_SIG1;
2127 }
2128
2129 // check for zeros (possibly from non-canonical values)
2130 if (C1 == 0x0ull) {
2131 // x is 0
2132 res = 0x00000000;
2133 BID_RETURN (res);
2134 }
2135 // x is not special and is not zero
2136
2137 // q = nr. of decimal digits in x (1 <= q <= 54)
2138 // determine first the nr. of bits in x
2139 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
2140 // split the 64-bit value in two 32-bit halves to avoid rounding errors
2141 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
2142 tmp1.d = (double) (C1 >> 32); // exact conversion
2143 x_nr_bits =
2144 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2145 } else { // x < 2^32
2146 tmp1.d = (double) C1; // exact conversion
2147 x_nr_bits =
2148 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2149 }
2150 } else { // if x < 2^53
2151 tmp1.d = (double) C1; // exact conversion
2152 x_nr_bits =
2153 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
2154 }
2155 q = __bid_nr_digits[x_nr_bits - 1].digits;
2156 if (q == 0) {
2157 q = __bid_nr_digits[x_nr_bits - 1].digits1;
2158 if (C1 >= __bid_nr_digits[x_nr_bits - 1].threshold_lo)
2159 q++;
2160 }
2161 exp = x_exp - 398; // unbiased exponent
2162
2163 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
2164 // set invalid flag
2165 *pfpsf |= INVALID_EXCEPTION;
2166 // return Integer Indefinite
2167 res = 0x8000000000000000ull;
2168 BID_RETURN (res);
2169 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
2170 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
2171 // so x rounded to an integer may or may not fit in a signed 64-bit int
2172 // the cases that do not fit are identified here; the ones that fit
2173 // fall through and will be handled with other cases further,
2174 // under '1 <= q + exp <= 19'
2175 if (x_sign) { // if n < 0 and q + exp = 19
2176 // if n <= -2^63 - 1/2 then n is too large
2177 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
2178 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
2179 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
2180 // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
2181 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2182 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
2183 // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
2184 if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
2185 // set invalid flag
2186 *pfpsf |= INVALID_EXCEPTION;
2187 // return Integer Indefinite
2188 res = 0x8000000000000000ull;
2189 BID_RETURN (res);
2190 }
2191 // else cases that can be rounded to a 64-bit int fall through
2192 // to '1 <= q + exp <= 19'
2193 } else { // if n > 0 and q + exp = 19
2194 // if n >= 2^63 - 1/2 then n is too large
2195 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
2196 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
2197 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
2198 // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
2199 C.w[1] = 0x0000000000000004ull;
2200 C.w[0] = 0xfffffffffffffffbull;
2201 // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
2202 __mul_64x64_to_128MACH (C, C1, __bid_ten2k64[20 - q]);
2203 if (C.w[1] > 0x04ull ||
2204 (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
2205 // set invalid flag
2206 *pfpsf |= INVALID_EXCEPTION;
2207 // return Integer Indefinite
2208 res = 0x8000000000000000ull;
2209 BID_RETURN (res);
2210 }
2211 // else cases that can be rounded to a 64-bit int fall through
2212 // to '1 <= q + exp <= 19'
2213 } // end else if n > 0 and q + exp = 19
2214 } // end else if ((q + exp) == 19)
2215
2216 // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
2217 // Note: some of the cases tested for above fall through to this point
2218 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
2219 // set inexact flag
2220 *pfpsf |= INEXACT_EXCEPTION;
2221 // return 0
2222 res = 0x0000000000000000ull;
2223 BID_RETURN (res);
2224 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
2225 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
2226 // res = 0
2227 // else
2228 // res = +/-1
2229 ind = q - 1; // 0 <= ind <= 15
2230 if (C1 < __bid_midpoint64[ind]) {
2231 res = 0x0000000000000000ull; // return 0
2232 } else if (x_sign) { // n < 0
2233 res = 0xffffffffffffffffull; // return -1
2234 } else { // n > 0
2235 res = 0x0000000000000001ull; // return +1
2236 }
2237 // set inexact flag
2238 *pfpsf |= INEXACT_EXCEPTION;
2239 } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
2240 // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
2241 // to nearest to a 64-bit signed integer
2242 if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
2243 ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
2244 // chop off ind digits from the lower part of C1
2245 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
2246 C1 = C1 + __bid_midpoint64[ind - 1];
2247 // calculate C* and f*
2248 // C* is actually floor(C*) in this case
2249 // C* and f* need shifting and masking, as shown by
2250 // __bid_shiftright128[] and __bid_maskhigh128[]
2251 // 1 <= x <= 15
2252 // kx = 10^(-x) = __bid_ten2mk64[ind - 1]
2253 // C* = (C1 + 1/2 * 10^x) * 10^(-x)
2254 // the approximation of 10^(-x) was rounded up to 54 bits
2255 __mul_64x64_to_128MACH (P128, C1, __bid_ten2mk64[ind - 1]);
2256 Cstar = P128.w[1];
2257 fstar.w[1] = P128.w[1] & __bid_maskhigh128[ind - 1];
2258 fstar.w[0] = P128.w[0];
2259 // the top Ex bits of 10^(-x) are T* = __bid_ten2mk128trunc[ind].w[0], e.g.
2260 // if x=1, T*=__bid_ten2mk128trunc[0].w[0]=0x1999999999999999
2261 // if (0 < f* < 10^(-x)) then the result is a midpoint
2262 // if floor(C*) is even then C* = floor(C*) - logical right
2263 // shift; C* has p decimal digits, correct by Prop. 1)
2264 // else if floor(C*) is odd C* = floor(C*)-1 (logical right
2265 // shift; C* has p decimal digits, correct by Pr. 1)
2266 // else
2267 // C* = floor(C*) (logical right shift; C has p decimal digits,
2268 // correct by Property 1)
2269 // n = C* * 10^(e+x)
2270
2271 // shift right C* by Ex-64 = __bid_shiftright128[ind]
2272 shift = __bid_shiftright128[ind - 1]; // 0 <= shift <= 39
2273 Cstar = Cstar >> shift;
2274 // determine inexactness of the rounding of C*
2275 // if (0 < f* - 1/2 < 10^(-x)) then
2276 // the result is exact
2277 // else // if (f* - 1/2 > T*) then
2278 // the result is inexact
2279 if (ind - 1 <= 2) {
2280 if (fstar.w[0] > 0x8000000000000000ull) {
2281 // f* > 1/2 and the result may be exact
2282 tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
2283 if ((tmp64 > __bid_ten2mk128trunc[ind - 1].w[1])) {
2284 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
2285 // __bid_ten2mk128[ind -1].w[1]
2286 // set the inexact flag
2287 *pfpsf |= INEXACT_EXCEPTION;
2288 } // else the result is exact
2289 } else { // the result is inexact; f2* <= 1/2
2290 // set the inexact flag
2291 *pfpsf |= INEXACT_EXCEPTION;
2292 }
2293 } else { // if 3 <= ind - 1 <= 14
2294 if (fstar.w[1] > __bid_one_half128[ind - 1] ||
2295 (fstar.w[1] == __bid_one_half128[ind - 1] && fstar.w[0])) {
2296 // f2* > 1/2 and the result may be exact
2297 // Calculate f2* - 1/2
2298 tmp64 = fstar.w[1] - __bid_one_half128[ind - 1];
2299 if (tmp64 || fstar.w[0] > __bid_ten2mk128trunc[ind - 1].w[1]) {
2300 // __bid_ten2mk128trunc[ind -1].w[1] is identical to
2301 // __bid_ten2mk128[ind -1].w[1]
2302 // set the inexact flag
2303 *pfpsf |= INEXACT_EXCEPTION;
2304 } // else the result is exact
2305 } else { // the result is inexact; f2* <= 1/2
2306 // set the inexact flag
2307 *pfpsf |= INEXACT_EXCEPTION;
2308 }
2309 }
2310
2311 // if the result was a midpoint it was rounded away from zero
2312 if (x_sign)
2313 res = -Cstar;
2314 else
2315 res = Cstar;
2316 } else if (exp == 0) {
2317 // 1 <= q <= 16
2318 // res = +/-C (exact)
2319 if (x_sign)
2320 res = -C1;
2321 else
2322 res = C1;
2323 } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
2324 // (the upper limit of 20 on q + exp is due to the fact that
2325 // +/-C * 10^exp is guaranteed to fit in 64 bits)
2326 // res = +/-C * 10^exp (exact)
2327 if (x_sign)
2328 res = -C1 * __bid_ten2k64[exp];
2329 else
2330 res = C1 * __bid_ten2k64[exp];
2331 }
2332 }
2333 BID_RETURN (res);
2334 }