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