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