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 } 2271