comparison libgcc/config/libbid/bid64_to_int64.c @ 0:a06113de4d67

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