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