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