1 /* Copyright (C) 2007-2020 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 * BID128_to_int64_rnint 28 ****************************************************************************/ 29 30 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_rnint, 31 x) 32 33 SINT64 res; 34 UINT64 x_sign; 35 UINT64 x_exp; 36 int exp; // unbiased exponent 37 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 38 UINT64 tmp64; 39 BID_UI64DOUBLE tmp1; 40 unsigned int x_nr_bits; 41 int q, ind, shift; 42 UINT128 C1, C; 43 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 44 UINT256 fstar; 45 UINT256 P256; 46 47 // unpack x 48 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 49 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 50 C1.w[1] = x.w[1] & MASK_COEFF; 51 C1.w[0] = x.w[0]; 52 53 // check for NaN or Infinity 54 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 55 // x is special 56 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 57 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 58 // set invalid flag 59 *pfpsf |= INVALID_EXCEPTION; 60 // return Integer Indefinite 61 res = 0x8000000000000000ull; 62 } else { // x is QNaN 63 // set invalid flag 64 *pfpsf |= INVALID_EXCEPTION; 65 // return Integer Indefinite 66 res = 0x8000000000000000ull; 67 } 68 BID_RETURN (res); 69 } else { // x is not a NaN, so it must be infinity 70 if (!x_sign) { // x is +inf 71 // set invalid flag 72 *pfpsf |= INVALID_EXCEPTION; 73 // return Integer Indefinite 74 res = 0x8000000000000000ull; 75 } else { // x is -inf 76 // set invalid flag 77 *pfpsf |= INVALID_EXCEPTION; 78 // return Integer Indefinite 79 res = 0x8000000000000000ull; 80 } 81 BID_RETURN (res); 82 } 83 } 84 // check for non-canonical values (after the check for special values) 85 if ((C1.w[1] > 0x0001ed09bead87c0ull) || 86 (C1.w[1] == 0x0001ed09bead87c0ull 87 && (C1.w[0] > 0x378d8e63ffffffffull)) 88 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 89 res = 0x0000000000000000ull; 90 BID_RETURN (res); 91 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 92 // x is 0 93 res = 0x0000000000000000ull; 94 BID_RETURN (res); 95 } else { // x is not special and is not zero 96 97 // q = nr. of decimal digits in x 98 // determine first the nr. of bits in x 99 if (C1.w[1] == 0) { 100 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 101 // split the 64-bit value in two 32-bit halves to avoid rounding errors 102 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 103 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 104 x_nr_bits = 105 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 106 } else { // x < 2^32 107 tmp1.d = (double) (C1.w[0]); // exact conversion 108 x_nr_bits = 109 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 110 } 111 } else { // if x < 2^53 112 tmp1.d = (double) C1.w[0]; // exact conversion 113 x_nr_bits = 114 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 115 } 116 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 117 tmp1.d = (double) C1.w[1]; // exact conversion 118 x_nr_bits = 119 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 120 } 121 q = nr_digits[x_nr_bits - 1].digits; 122 if (q == 0) { 123 q = nr_digits[x_nr_bits - 1].digits1; 124 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 125 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 126 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 127 q++; 128 } 129 exp = (x_exp >> 49) - 6176; 130 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 131 // set invalid flag 132 *pfpsf |= INVALID_EXCEPTION; 133 // return Integer Indefinite 134 res = 0x8000000000000000ull; 135 BID_RETURN (res); 136 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 137 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 138 // so x rounded to an integer may or may not fit in a signed 64-bit int 139 // the cases that do not fit are identified here; the ones that fit 140 // fall through and will be handled with other cases further, 141 // under '1 <= q + exp <= 19' 142 if (x_sign) { // if n < 0 and q + exp = 19 143 // if n < -2^63 - 1/2 then n is too large 144 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2 145 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=34 146 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=34 147 C.w[1] = 0x0000000000000005ull; 148 C.w[0] = 0000000000000005ull; 149 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 150 // 10^(20-q) is 64-bit, and so is C1 151 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 152 } else if (q == 20) { 153 ; // C1 * 10^0 = C1 154 } else { // if 21 <= q <= 34 155 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 156 } 157 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 158 // set invalid flag 159 *pfpsf |= INVALID_EXCEPTION; 160 // return Integer Indefinite 161 res = 0x8000000000000000ull; 162 BID_RETURN (res); 163 } 164 // else cases that can be rounded to a 64-bit int fall through 165 // to '1 <= q + exp <= 19' 166 } else { // if n > 0 and q + exp = 19 167 // if n >= 2^63 - 1/2 then n is too large 168 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2 169 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34 170 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34 171 C.w[1] = 0x0000000000000004ull; 172 C.w[0] = 0xfffffffffffffffbull; 173 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 174 // 10^(20-q) is 64-bit, and so is C1 175 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 176 } else if (q == 20) { 177 ; // C1 * 10^0 = C1 178 } else { // if 21 <= q <= 34 179 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 180 } 181 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 182 // set invalid flag 183 *pfpsf |= INVALID_EXCEPTION; 184 // return Integer Indefinite 185 res = 0x8000000000000000ull; 186 BID_RETURN (res); 187 } 188 // else cases that can be rounded to a 64-bit int fall through 189 // to '1 <= q + exp <= 19' 190 } 191 } 192 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2 193 // Note: some of the cases tested for above fall through to this point 194 // Restore C1 which may have been modified above 195 C1.w[1] = x.w[1] & MASK_COEFF; 196 C1.w[0] = x.w[0]; 197 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1) 198 // return 0 199 res = 0x0000000000000000ull; 200 BID_RETURN (res); 201 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1) 202 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1) 203 // res = 0 204 // else 205 // res = +/-1 206 ind = q - 1; 207 if (ind <= 18) { // 0 <= ind <= 18 208 if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) { 209 res = 0x0000000000000000ull; // return 0 210 } else if (x_sign) { // n < 0 211 res = 0xffffffffffffffffull; // return -1 212 } else { // n > 0 213 res = 0x0000000000000001ull; // return +1 214 } 215 } else { // 19 <= ind <= 33 216 if ((C1.w[1] < midpoint128[ind - 19].w[1]) 217 || ((C1.w[1] == midpoint128[ind - 19].w[1]) 218 && (C1.w[0] <= midpoint128[ind - 19].w[0]))) { 219 res = 0x0000000000000000ull; // return 0 220 } else if (x_sign) { // n < 0 221 res = 0xffffffffffffffffull; // return -1 222 } else { // n > 0 223 res = 0x0000000000000001ull; // return +1 224 } 225 } 226 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 227 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded 228 // to nearest to a 64-bit signed integer 229 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 230 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 231 // chop off ind digits from the lower part of C1 232 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits 233 tmp64 = C1.w[0]; 234 if (ind <= 19) { 235 C1.w[0] = C1.w[0] + midpoint64[ind - 1]; 236 } else { 237 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0]; 238 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1]; 239 } 240 if (C1.w[0] < tmp64) 241 C1.w[1]++; 242 // calculate C* and f* 243 // C* is actually floor(C*) in this case 244 // C* and f* need shifting and masking, as shown by 245 // shiftright128[] and maskhigh128[] 246 // 1 <= x <= 33 247 // kx = 10^(-x) = ten2mk128[ind - 1] 248 // C* = (C1 + 1/2 * 10^x) * 10^(-x) 249 // the approximation of 10^(-x) was rounded up to 118 bits 250 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 251 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 252 Cstar.w[1] = P256.w[3]; 253 Cstar.w[0] = P256.w[2]; 254 fstar.w[3] = 0; 255 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 256 fstar.w[1] = P256.w[1]; 257 fstar.w[0] = P256.w[0]; 258 } else { // 22 <= ind - 1 <= 33 259 Cstar.w[1] = 0; 260 Cstar.w[0] = P256.w[3]; 261 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 262 fstar.w[2] = P256.w[2]; 263 fstar.w[1] = P256.w[1]; 264 fstar.w[0] = P256.w[0]; 265 } 266 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 267 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 268 // if (0 < f* < 10^(-x)) then the result is a midpoint 269 // if floor(C*) is even then C* = floor(C*) - logical right 270 // shift; C* has p decimal digits, correct by Prop. 1) 271 // else if floor(C*) is odd C* = floor(C*)-1 (logical right 272 // shift; C* has p decimal digits, correct by Pr. 1) 273 // else 274 // C* = floor(C*) (logical right shift; C has p decimal digits, 275 // correct by Property 1) 276 // n = C* * 10^(e+x) 277 278 // shift right C* by Ex-128 = shiftright128[ind] 279 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 280 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 281 Cstar.w[0] = 282 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 283 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 284 } else { // 22 <= ind - 1 <= 33 285 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 286 } 287 // if the result was a midpoint it was rounded away from zero, so 288 // it will need a correction 289 // check for midpoints 290 if ((fstar.w[3] == 0) && (fstar.w[2] == 0) && 291 (fstar.w[1] || fstar.w[0]) && 292 (fstar.w[1] < ten2mk128trunc[ind - 1].w[1] || 293 (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] && 294 fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) { 295 // the result is a midpoint; round to nearest 296 if (Cstar.w[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD] 297 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1 298 Cstar.w[0]--; // Cstar.w[0] is now even 299 } // else MP in [ODD, EVEN] 300 } 301 if (x_sign) 302 res = -Cstar.w[0]; 303 else 304 res = Cstar.w[0]; 305 } else if (exp == 0) { 306 // 1 <= q <= 19 307 // res = +/-C (exact) 308 if (x_sign) 309 res = -C1.w[0]; 310 else 311 res = C1.w[0]; 312 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 313 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 314 if (x_sign) 315 res = -C1.w[0] * ten2k64[exp]; 316 else 317 res = C1.w[0] * ten2k64[exp]; 318 } 319 } 320 } 321 322 BID_RETURN (res); 323 } 324 325 /***************************************************************************** 326 * BID128_to_int64_xrnint 327 ****************************************************************************/ 328 329 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, 330 bid128_to_int64_xrnint, x) 331 332 SINT64 res; 333 UINT64 x_sign; 334 UINT64 x_exp; 335 int exp; // unbiased exponent 336 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 337 UINT64 tmp64, tmp64A; 338 BID_UI64DOUBLE tmp1; 339 unsigned int x_nr_bits; 340 int q, ind, shift; 341 UINT128 C1, C; 342 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 343 UINT256 fstar; 344 UINT256 P256; 345 346 // unpack x 347 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 348 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 349 C1.w[1] = x.w[1] & MASK_COEFF; 350 C1.w[0] = x.w[0]; 351 352 // check for NaN or Infinity 353 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 354 // x is special 355 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 356 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 357 // set invalid flag 358 *pfpsf |= INVALID_EXCEPTION; 359 // return Integer Indefinite 360 res = 0x8000000000000000ull; 361 } else { // x is QNaN 362 // set invalid flag 363 *pfpsf |= INVALID_EXCEPTION; 364 // return Integer Indefinite 365 res = 0x8000000000000000ull; 366 } 367 BID_RETURN (res); 368 } else { // x is not a NaN, so it must be infinity 369 if (!x_sign) { // x is +inf 370 // set invalid flag 371 *pfpsf |= INVALID_EXCEPTION; 372 // return Integer Indefinite 373 res = 0x8000000000000000ull; 374 } else { // x is -inf 375 // set invalid flag 376 *pfpsf |= INVALID_EXCEPTION; 377 // return Integer Indefinite 378 res = 0x8000000000000000ull; 379 } 380 BID_RETURN (res); 381 } 382 } 383 // check for non-canonical values (after the check for special values) 384 if ((C1.w[1] > 0x0001ed09bead87c0ull) 385 || (C1.w[1] == 0x0001ed09bead87c0ull 386 && (C1.w[0] > 0x378d8e63ffffffffull)) 387 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 388 res = 0x0000000000000000ull; 389 BID_RETURN (res); 390 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 391 // x is 0 392 res = 0x0000000000000000ull; 393 BID_RETURN (res); 394 } else { // x is not special and is not zero 395 396 // q = nr. of decimal digits in x 397 // determine first the nr. of bits in x 398 if (C1.w[1] == 0) { 399 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 400 // split the 64-bit value in two 32-bit halves to avoid rounding errors 401 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 402 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 403 x_nr_bits = 404 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 405 } else { // x < 2^32 406 tmp1.d = (double) (C1.w[0]); // exact conversion 407 x_nr_bits = 408 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 409 } 410 } else { // if x < 2^53 411 tmp1.d = (double) C1.w[0]; // exact conversion 412 x_nr_bits = 413 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 414 } 415 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 416 tmp1.d = (double) C1.w[1]; // exact conversion 417 x_nr_bits = 418 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 419 } 420 q = nr_digits[x_nr_bits - 1].digits; 421 if (q == 0) { 422 q = nr_digits[x_nr_bits - 1].digits1; 423 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 424 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 425 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 426 q++; 427 } 428 exp = (x_exp >> 49) - 6176; 429 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 430 // set invalid flag 431 *pfpsf |= INVALID_EXCEPTION; 432 // return Integer Indefinite 433 res = 0x8000000000000000ull; 434 BID_RETURN (res); 435 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 436 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 437 // so x rounded to an integer may or may not fit in a signed 64-bit int 438 // the cases that do not fit are identified here; the ones that fit 439 // fall through and will be handled with other cases further, 440 // under '1 <= q + exp <= 19' 441 if (x_sign) { // if n < 0 and q + exp = 19 442 // if n < -2^63 - 1/2 then n is too large 443 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2 444 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=34 445 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=34 446 C.w[1] = 0x0000000000000005ull; 447 C.w[0] = 0000000000000005ull; 448 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 449 // 10^(20-q) is 64-bit, and so is C1 450 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 451 } else if (q == 20) { 452 ; // C1 * 10^0 = C1 453 } else { // if 21 <= q <= 34 454 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 455 } 456 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 457 // set invalid flag 458 *pfpsf |= INVALID_EXCEPTION; 459 // return Integer Indefinite 460 res = 0x8000000000000000ull; 461 BID_RETURN (res); 462 } 463 // else cases that can be rounded to a 64-bit int fall through 464 // to '1 <= q + exp <= 19' 465 } else { // if n > 0 and q + exp = 19 466 // if n >= 2^63 - 1/2 then n is too large 467 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2 468 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34 469 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34 470 C.w[1] = 0x0000000000000004ull; 471 C.w[0] = 0xfffffffffffffffbull; 472 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 473 // 10^(20-q) is 64-bit, and so is C1 474 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 475 } else if (q == 20) { 476 ; // C1 * 10^0 = C1 477 } else { // if 21 <= q <= 34 478 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 479 } 480 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 481 // set invalid flag 482 *pfpsf |= INVALID_EXCEPTION; 483 // return Integer Indefinite 484 res = 0x8000000000000000ull; 485 BID_RETURN (res); 486 } 487 // else cases that can be rounded to a 64-bit int fall through 488 // to '1 <= q + exp <= 19' 489 } 490 } 491 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2 492 // Note: some of the cases tested for above fall through to this point 493 // Restore C1 which may have been modified above 494 C1.w[1] = x.w[1] & MASK_COEFF; 495 C1.w[0] = x.w[0]; 496 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1) 497 // set inexact flag 498 *pfpsf |= INEXACT_EXCEPTION; 499 // return 0 500 res = 0x0000000000000000ull; 501 BID_RETURN (res); 502 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1) 503 // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1) 504 // res = 0 505 // else 506 // res = +/-1 507 ind = q - 1; 508 if (ind <= 18) { // 0 <= ind <= 18 509 if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) { 510 res = 0x0000000000000000ull; // return 0 511 } else if (x_sign) { // n < 0 512 res = 0xffffffffffffffffull; // return -1 513 } else { // n > 0 514 res = 0x0000000000000001ull; // return +1 515 } 516 } else { // 19 <= ind <= 33 517 if ((C1.w[1] < midpoint128[ind - 19].w[1]) 518 || ((C1.w[1] == midpoint128[ind - 19].w[1]) 519 && (C1.w[0] <= midpoint128[ind - 19].w[0]))) { 520 res = 0x0000000000000000ull; // return 0 521 } else if (x_sign) { // n < 0 522 res = 0xffffffffffffffffull; // return -1 523 } else { // n > 0 524 res = 0x0000000000000001ull; // return +1 525 } 526 } 527 // set inexact flag 528 *pfpsf |= INEXACT_EXCEPTION; 529 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 530 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded 531 // to nearest to a 64-bit signed integer 532 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 533 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 534 // chop off ind digits from the lower part of C1 535 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits 536 tmp64 = C1.w[0]; 537 if (ind <= 19) { 538 C1.w[0] = C1.w[0] + midpoint64[ind - 1]; 539 } else { 540 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0]; 541 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1]; 542 } 543 if (C1.w[0] < tmp64) 544 C1.w[1]++; 545 // calculate C* and f* 546 // C* is actually floor(C*) in this case 547 // C* and f* need shifting and masking, as shown by 548 // shiftright128[] and maskhigh128[] 549 // 1 <= x <= 33 550 // kx = 10^(-x) = ten2mk128[ind - 1] 551 // C* = (C1 + 1/2 * 10^x) * 10^(-x) 552 // the approximation of 10^(-x) was rounded up to 118 bits 553 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 554 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 555 Cstar.w[1] = P256.w[3]; 556 Cstar.w[0] = P256.w[2]; 557 fstar.w[3] = 0; 558 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 559 fstar.w[1] = P256.w[1]; 560 fstar.w[0] = P256.w[0]; 561 } else { // 22 <= ind - 1 <= 33 562 Cstar.w[1] = 0; 563 Cstar.w[0] = P256.w[3]; 564 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 565 fstar.w[2] = P256.w[2]; 566 fstar.w[1] = P256.w[1]; 567 fstar.w[0] = P256.w[0]; 568 } 569 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 570 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 571 // if (0 < f* < 10^(-x)) then the result is a midpoint 572 // if floor(C*) is even then C* = floor(C*) - logical right 573 // shift; C* has p decimal digits, correct by Prop. 1) 574 // else if floor(C*) is odd C* = floor(C*)-1 (logical right 575 // shift; C* has p decimal digits, correct by Pr. 1) 576 // else 577 // C* = floor(C*) (logical right shift; C has p decimal digits, 578 // correct by Property 1) 579 // n = C* * 10^(e+x) 580 581 // shift right C* by Ex-128 = shiftright128[ind] 582 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 583 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 584 Cstar.w[0] = 585 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 586 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 587 } else { // 22 <= ind - 1 <= 33 588 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 589 } 590 // determine inexactness of the rounding of C* 591 // if (0 < f* - 1/2 < 10^(-x)) then 592 // the result is exact 593 // else // if (f* - 1/2 > T*) then 594 // the result is inexact 595 if (ind - 1 <= 2) { 596 if (fstar.w[1] > 0x8000000000000000ull || 597 (fstar.w[1] == 0x8000000000000000ull 598 && fstar.w[0] > 0x0ull)) { 599 // f* > 1/2 and the result may be exact 600 tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2 601 if (tmp64 > ten2mk128trunc[ind - 1].w[1] 602 || (tmp64 == ten2mk128trunc[ind - 1].w[1] 603 && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) { 604 // set the inexact flag 605 *pfpsf |= INEXACT_EXCEPTION; 606 } // else the result is exact 607 } else { // the result is inexact; f2* <= 1/2 608 // set the inexact flag 609 *pfpsf |= INEXACT_EXCEPTION; 610 } 611 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 612 if (fstar.w[3] > 0x0 || 613 (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) || 614 (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] && 615 (fstar.w[1] || fstar.w[0]))) { 616 // f2* > 1/2 and the result may be exact 617 // Calculate f2* - 1/2 618 tmp64 = fstar.w[2] - onehalf128[ind - 1]; 619 tmp64A = fstar.w[3]; 620 if (tmp64 > fstar.w[2]) 621 tmp64A--; 622 if (tmp64A || tmp64 623 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 624 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 625 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 626 // set the inexact flag 627 *pfpsf |= INEXACT_EXCEPTION; 628 } // else the result is exact 629 } else { // the result is inexact; f2* <= 1/2 630 // set the inexact flag 631 *pfpsf |= INEXACT_EXCEPTION; 632 } 633 } else { // if 22 <= ind <= 33 634 if (fstar.w[3] > onehalf128[ind - 1] || 635 (fstar.w[3] == onehalf128[ind - 1] && 636 (fstar.w[2] || fstar.w[1] || fstar.w[0]))) { 637 // f2* > 1/2 and the result may be exact 638 // Calculate f2* - 1/2 639 tmp64 = fstar.w[3] - onehalf128[ind - 1]; 640 if (tmp64 || fstar.w[2] 641 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 642 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 643 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 644 // set the inexact flag 645 *pfpsf |= INEXACT_EXCEPTION; 646 } // else the result is exact 647 } else { // the result is inexact; f2* <= 1/2 648 // set the inexact flag 649 *pfpsf |= INEXACT_EXCEPTION; 650 } 651 } 652 653 // if the result was a midpoint it was rounded away from zero, so 654 // it will need a correction 655 // check for midpoints 656 if ((fstar.w[3] == 0) && (fstar.w[2] == 0) && 657 (fstar.w[1] || fstar.w[0]) && 658 (fstar.w[1] < ten2mk128trunc[ind - 1].w[1] || 659 (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] && 660 fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) { 661 // the result is a midpoint; round to nearest 662 if (Cstar.w[0] & 0x01) { // Cstar.w[0] is odd; MP in [EVEN, ODD] 663 // if floor(C*) is odd C = floor(C*) - 1; the result >= 1 664 Cstar.w[0]--; // Cstar.w[0] is now even 665 } // else MP in [ODD, EVEN] 666 } 667 if (x_sign) 668 res = -Cstar.w[0]; 669 else 670 res = Cstar.w[0]; 671 } else if (exp == 0) { 672 // 1 <= q <= 19 673 // res = +/-C (exact) 674 if (x_sign) 675 res = -C1.w[0]; 676 else 677 res = C1.w[0]; 678 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 679 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 680 if (x_sign) 681 res = -C1.w[0] * ten2k64[exp]; 682 else 683 res = C1.w[0] * ten2k64[exp]; 684 } 685 } 686 } 687 688 BID_RETURN (res); 689 } 690 691 /***************************************************************************** 692 * BID128_to_int64_floor 693 ****************************************************************************/ 694 695 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_floor, 696 x) 697 698 SINT64 res; 699 UINT64 x_sign; 700 UINT64 x_exp; 701 int exp; // unbiased exponent 702 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 703 BID_UI64DOUBLE tmp1; 704 unsigned int x_nr_bits; 705 int q, ind, shift; 706 UINT128 C1, C; 707 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 708 UINT256 fstar; 709 UINT256 P256; 710 711 // unpack x 712 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 713 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 714 C1.w[1] = x.w[1] & MASK_COEFF; 715 C1.w[0] = x.w[0]; 716 717 // check for NaN or Infinity 718 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 719 // x is special 720 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 721 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 722 // set invalid flag 723 *pfpsf |= INVALID_EXCEPTION; 724 // return Integer Indefinite 725 res = 0x8000000000000000ull; 726 } else { // x is QNaN 727 // set invalid flag 728 *pfpsf |= INVALID_EXCEPTION; 729 // return Integer Indefinite 730 res = 0x8000000000000000ull; 731 } 732 BID_RETURN (res); 733 } else { // x is not a NaN, so it must be infinity 734 if (!x_sign) { // x is +inf 735 // set invalid flag 736 *pfpsf |= INVALID_EXCEPTION; 737 // return Integer Indefinite 738 res = 0x8000000000000000ull; 739 } else { // x is -inf 740 // set invalid flag 741 *pfpsf |= INVALID_EXCEPTION; 742 // return Integer Indefinite 743 res = 0x8000000000000000ull; 744 } 745 BID_RETURN (res); 746 } 747 } 748 // check for non-canonical values (after the check for special values) 749 if ((C1.w[1] > 0x0001ed09bead87c0ull) 750 || (C1.w[1] == 0x0001ed09bead87c0ull 751 && (C1.w[0] > 0x378d8e63ffffffffull)) 752 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 753 res = 0x0000000000000000ull; 754 BID_RETURN (res); 755 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 756 // x is 0 757 res = 0x0000000000000000ull; 758 BID_RETURN (res); 759 } else { // x is not special and is not zero 760 761 // q = nr. of decimal digits in x 762 // determine first the nr. of bits in x 763 if (C1.w[1] == 0) { 764 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 765 // split the 64-bit value in two 32-bit halves to avoid rounding errors 766 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 767 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 768 x_nr_bits = 769 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 770 } else { // x < 2^32 771 tmp1.d = (double) (C1.w[0]); // exact conversion 772 x_nr_bits = 773 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 774 } 775 } else { // if x < 2^53 776 tmp1.d = (double) C1.w[0]; // exact conversion 777 x_nr_bits = 778 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 779 } 780 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 781 tmp1.d = (double) C1.w[1]; // exact conversion 782 x_nr_bits = 783 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 784 } 785 q = nr_digits[x_nr_bits - 1].digits; 786 if (q == 0) { 787 q = nr_digits[x_nr_bits - 1].digits1; 788 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 789 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 790 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 791 q++; 792 } 793 exp = (x_exp >> 49) - 6176; 794 795 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 796 // set invalid flag 797 *pfpsf |= INVALID_EXCEPTION; 798 // return Integer Indefinite 799 res = 0x8000000000000000ull; 800 BID_RETURN (res); 801 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 802 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 803 // so x rounded to an integer may or may not fit in a signed 64-bit int 804 // the cases that do not fit are identified here; the ones that fit 805 // fall through and will be handled with other cases further, 806 // under '1 <= q + exp <= 19' 807 if (x_sign) { // if n < 0 and q + exp = 19 808 // if n < -2^63 then n is too large 809 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 810 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 10*2^63, 1<=q<=34 811 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=34 812 C.w[1] = 0x0000000000000005ull; 813 C.w[0] = 0x0000000000000000ull; 814 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 815 // 10^(20-q) is 64-bit, and so is C1 816 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 817 } else if (q == 20) { 818 ; // C1 * 10^0 = C1 819 } else { // if 21 <= q <= 34 820 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 821 } 822 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 823 // set invalid flag 824 *pfpsf |= INVALID_EXCEPTION; 825 // return Integer Indefinite 826 res = 0x8000000000000000ull; 827 BID_RETURN (res); 828 } 829 // else cases that can be rounded to a 64-bit int fall through 830 // to '1 <= q + exp <= 19' 831 } else { // if n > 0 and q + exp = 19 832 // if n >= 2^63 then n is too large 833 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63 834 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34 835 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34 836 C.w[1] = 0x0000000000000005ull; 837 C.w[0] = 0x0000000000000000ull; 838 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 839 // 10^(20-q) is 64-bit, and so is C1 840 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 841 } else if (q == 20) { 842 ; // C1 * 10^0 = C1 843 } else { // if 21 <= q <= 34 844 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 845 } 846 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 847 // set invalid flag 848 *pfpsf |= INVALID_EXCEPTION; 849 // return Integer Indefinite 850 res = 0x8000000000000000ull; 851 BID_RETURN (res); 852 } 853 // else cases that can be rounded to a 64-bit int fall through 854 // to '1 <= q + exp <= 19' 855 } 856 } 857 // n is not too large to be converted to int64: -2^63-1 < n < 2^63 858 // Note: some of the cases tested for above fall through to this point 859 // Restore C1 which may have been modified above 860 C1.w[1] = x.w[1] & MASK_COEFF; 861 C1.w[0] = x.w[0]; 862 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 863 // return -1 or 0 864 if (x_sign) 865 res = 0xffffffffffffffffull; 866 else 867 res = 0x0000000000000000ull; 868 BID_RETURN (res); 869 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 870 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded 871 // toward zero to a 64-bit signed integer 872 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 873 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 874 // chop off ind digits from the lower part of C1 875 // C1 fits in 127 bits 876 // calculate C* and f* 877 // C* is actually floor(C*) in this case 878 // C* and f* need shifting and masking, as shown by 879 // shiftright128[] and maskhigh128[] 880 // 1 <= x <= 33 881 // kx = 10^(-x) = ten2mk128[ind - 1] 882 // C* = C1 * 10^(-x) 883 // the approximation of 10^(-x) was rounded up to 118 bits 884 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 885 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 886 Cstar.w[1] = P256.w[3]; 887 Cstar.w[0] = P256.w[2]; 888 fstar.w[3] = 0; 889 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 890 fstar.w[1] = P256.w[1]; 891 fstar.w[0] = P256.w[0]; 892 } else { // 22 <= ind - 1 <= 33 893 Cstar.w[1] = 0; 894 Cstar.w[0] = P256.w[3]; 895 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 896 fstar.w[2] = P256.w[2]; 897 fstar.w[1] = P256.w[1]; 898 fstar.w[0] = P256.w[0]; 899 } 900 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 901 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 902 // C* = floor(C*) (logical right shift; C has p decimal digits, 903 // correct by Property 1) 904 // n = C* * 10^(e+x) 905 906 // shift right C* by Ex-128 = shiftright128[ind] 907 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 908 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 909 Cstar.w[0] = 910 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 911 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 912 } else { // 22 <= ind - 1 <= 33 913 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 914 } 915 // if the result is negative and inexact, need to add 1 to it 916 917 // determine inexactness of the rounding of C* 918 // if (0 < f* < 10^(-x)) then 919 // the result is exact 920 // else // if (f* > T*) then 921 // the result is inexact 922 if (ind - 1 <= 2) { 923 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] || 924 (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] && 925 fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 926 if (x_sign) { // positive and inexact 927 Cstar.w[0]++; 928 if (Cstar.w[0] == 0x0) 929 Cstar.w[1]++; 930 } 931 } // else the result is exact 932 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 933 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 934 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 935 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 936 if (x_sign) { // positive and inexact 937 Cstar.w[0]++; 938 if (Cstar.w[0] == 0x0) 939 Cstar.w[1]++; 940 } 941 } // else the result is exact 942 } else { // if 22 <= ind <= 33 943 if (fstar.w[3] || fstar.w[2] 944 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 945 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 946 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 947 if (x_sign) { // positive and inexact 948 Cstar.w[0]++; 949 if (Cstar.w[0] == 0x0) 950 Cstar.w[1]++; 951 } 952 } // else the result is exact 953 } 954 955 if (x_sign) 956 res = -Cstar.w[0]; 957 else 958 res = Cstar.w[0]; 959 } else if (exp == 0) { 960 // 1 <= q <= 19 961 // res = +/-C (exact) 962 if (x_sign) 963 res = -C1.w[0]; 964 else 965 res = C1.w[0]; 966 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 967 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 968 if (x_sign) 969 res = -C1.w[0] * ten2k64[exp]; 970 else 971 res = C1.w[0] * ten2k64[exp]; 972 } 973 } 974 } 975 976 BID_RETURN (res); 977 } 978 979 /***************************************************************************** 980 * BID128_to_int64_xfloor 981 ****************************************************************************/ 982 983 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, 984 bid128_to_int64_xfloor, x) 985 986 SINT64 res; 987 UINT64 x_sign; 988 UINT64 x_exp; 989 int exp; // unbiased exponent 990 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 991 BID_UI64DOUBLE tmp1; 992 unsigned int x_nr_bits; 993 int q, ind, shift; 994 UINT128 C1, C; 995 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 996 UINT256 fstar; 997 UINT256 P256; 998 999 // unpack x 1000 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 1001 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 1002 C1.w[1] = x.w[1] & MASK_COEFF; 1003 C1.w[0] = x.w[0]; 1004 1005 // check for NaN or Infinity 1006 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 1007 // x is special 1008 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 1009 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 1010 // set invalid flag 1011 *pfpsf |= INVALID_EXCEPTION; 1012 // return Integer Indefinite 1013 res = 0x8000000000000000ull; 1014 } else { // x is QNaN 1015 // set invalid flag 1016 *pfpsf |= INVALID_EXCEPTION; 1017 // return Integer Indefinite 1018 res = 0x8000000000000000ull; 1019 } 1020 BID_RETURN (res); 1021 } else { // x is not a NaN, so it must be infinity 1022 if (!x_sign) { // x is +inf 1023 // set invalid flag 1024 *pfpsf |= INVALID_EXCEPTION; 1025 // return Integer Indefinite 1026 res = 0x8000000000000000ull; 1027 } else { // x is -inf 1028 // set invalid flag 1029 *pfpsf |= INVALID_EXCEPTION; 1030 // return Integer Indefinite 1031 res = 0x8000000000000000ull; 1032 } 1033 BID_RETURN (res); 1034 } 1035 } 1036 // check for non-canonical values (after the check for special values) 1037 if ((C1.w[1] > 0x0001ed09bead87c0ull) 1038 || (C1.w[1] == 0x0001ed09bead87c0ull 1039 && (C1.w[0] > 0x378d8e63ffffffffull)) 1040 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 1041 res = 0x0000000000000000ull; 1042 BID_RETURN (res); 1043 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 1044 // x is 0 1045 res = 0x0000000000000000ull; 1046 BID_RETURN (res); 1047 } else { // x is not special and is not zero 1048 1049 // q = nr. of decimal digits in x 1050 // determine first the nr. of bits in x 1051 if (C1.w[1] == 0) { 1052 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 1053 // split the 64-bit value in two 32-bit halves to avoid rounding errors 1054 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 1055 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 1056 x_nr_bits = 1057 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1058 } else { // x < 2^32 1059 tmp1.d = (double) (C1.w[0]); // exact conversion 1060 x_nr_bits = 1061 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1062 } 1063 } else { // if x < 2^53 1064 tmp1.d = (double) C1.w[0]; // exact conversion 1065 x_nr_bits = 1066 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1067 } 1068 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 1069 tmp1.d = (double) C1.w[1]; // exact conversion 1070 x_nr_bits = 1071 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1072 } 1073 q = nr_digits[x_nr_bits - 1].digits; 1074 if (q == 0) { 1075 q = nr_digits[x_nr_bits - 1].digits1; 1076 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 1077 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 1078 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 1079 q++; 1080 } 1081 exp = (x_exp >> 49) - 6176; 1082 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 1083 // set invalid flag 1084 *pfpsf |= INVALID_EXCEPTION; 1085 // return Integer Indefinite 1086 res = 0x8000000000000000ull; 1087 BID_RETURN (res); 1088 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 1089 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 1090 // so x rounded to an integer may or may not fit in a signed 64-bit int 1091 // the cases that do not fit are identified here; the ones that fit 1092 // fall through and will be handled with other cases further, 1093 // under '1 <= q + exp <= 19' 1094 if (x_sign) { // if n < 0 and q + exp = 19 1095 // if n < -2^63 then n is too large 1096 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 1097 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 10*2^63, 1<=q<=34 1098 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=34 1099 C.w[1] = 0x0000000000000005ull; 1100 C.w[0] = 0x0000000000000000ull; 1101 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1102 // 10^(20-q) is 64-bit, and so is C1 1103 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1104 } else if (q == 20) { 1105 ; // C1 * 10^0 = C1 1106 } else { // if 21 <= q <= 34 1107 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1108 } 1109 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 1110 // set invalid flag 1111 *pfpsf |= INVALID_EXCEPTION; 1112 // return Integer Indefinite 1113 res = 0x8000000000000000ull; 1114 BID_RETURN (res); 1115 } 1116 // else cases that can be rounded to a 64-bit int fall through 1117 // to '1 <= q + exp <= 19' 1118 } else { // if n > 0 and q + exp = 19 1119 // if n >= 2^63 then n is too large 1120 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63 1121 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34 1122 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34 1123 C.w[1] = 0x0000000000000005ull; 1124 C.w[0] = 0x0000000000000000ull; 1125 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1126 // 10^(20-q) is 64-bit, and so is C1 1127 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1128 } else if (q == 20) { 1129 ; // C1 * 10^0 = C1 1130 } else { // if 21 <= q <= 34 1131 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1132 } 1133 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 1134 // set invalid flag 1135 *pfpsf |= INVALID_EXCEPTION; 1136 // return Integer Indefinite 1137 res = 0x8000000000000000ull; 1138 BID_RETURN (res); 1139 } 1140 // else cases that can be rounded to a 64-bit int fall through 1141 // to '1 <= q + exp <= 19' 1142 } 1143 } 1144 // n is not too large to be converted to int64: -2^63-1 < n < 2^63 1145 // Note: some of the cases tested for above fall through to this point 1146 // Restore C1 which may have been modified above 1147 C1.w[1] = x.w[1] & MASK_COEFF; 1148 C1.w[0] = x.w[0]; 1149 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 1150 // set inexact flag 1151 *pfpsf |= INEXACT_EXCEPTION; 1152 // return -1 or 0 1153 if (x_sign) 1154 res = 0xffffffffffffffffull; 1155 else 1156 res = 0x0000000000000000ull; 1157 BID_RETURN (res); 1158 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 1159 // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded 1160 // toward zero to a 64-bit signed integer 1161 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 1162 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 1163 // chop off ind digits from the lower part of C1 1164 // C1 fits in 127 bits 1165 // calculate C* and f* 1166 // C* is actually floor(C*) in this case 1167 // C* and f* need shifting and masking, as shown by 1168 // shiftright128[] and maskhigh128[] 1169 // 1 <= x <= 33 1170 // kx = 10^(-x) = ten2mk128[ind - 1] 1171 // C* = C1 * 10^(-x) 1172 // the approximation of 10^(-x) was rounded up to 118 bits 1173 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 1174 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1175 Cstar.w[1] = P256.w[3]; 1176 Cstar.w[0] = P256.w[2]; 1177 fstar.w[3] = 0; 1178 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 1179 fstar.w[1] = P256.w[1]; 1180 fstar.w[0] = P256.w[0]; 1181 } else { // 22 <= ind - 1 <= 33 1182 Cstar.w[1] = 0; 1183 Cstar.w[0] = P256.w[3]; 1184 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 1185 fstar.w[2] = P256.w[2]; 1186 fstar.w[1] = P256.w[1]; 1187 fstar.w[0] = P256.w[0]; 1188 } 1189 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 1190 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 1191 // C* = floor(C*) (logical right shift; C has p decimal digits, 1192 // correct by Property 1) 1193 // n = C* * 10^(e+x) 1194 1195 // shift right C* by Ex-128 = shiftright128[ind] 1196 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 1197 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1198 Cstar.w[0] = 1199 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 1200 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 1201 } else { // 22 <= ind - 1 <= 33 1202 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 1203 } 1204 // if the result is negative and inexact, need to add 1 to it 1205 1206 // determine inexactness of the rounding of C* 1207 // if (0 < f* < 10^(-x)) then 1208 // the result is exact 1209 // else // if (f* > T*) then 1210 // the result is inexact 1211 if (ind - 1 <= 2) { 1212 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] || 1213 (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] && 1214 fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1215 if (x_sign) { // positive and inexact 1216 Cstar.w[0]++; 1217 if (Cstar.w[0] == 0x0) 1218 Cstar.w[1]++; 1219 } 1220 // set the inexact flag 1221 *pfpsf |= INEXACT_EXCEPTION; 1222 } // else the result is exact 1223 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 1224 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1225 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1226 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1227 if (x_sign) { // positive and inexact 1228 Cstar.w[0]++; 1229 if (Cstar.w[0] == 0x0) 1230 Cstar.w[1]++; 1231 } 1232 // set the inexact flag 1233 *pfpsf |= INEXACT_EXCEPTION; 1234 } // else the result is exact 1235 } else { // if 22 <= ind <= 33 1236 if (fstar.w[3] || fstar.w[2] 1237 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1238 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1239 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1240 if (x_sign) { // positive and inexact 1241 Cstar.w[0]++; 1242 if (Cstar.w[0] == 0x0) 1243 Cstar.w[1]++; 1244 } 1245 // set the inexact flag 1246 *pfpsf |= INEXACT_EXCEPTION; 1247 } // else the result is exact 1248 } 1249 1250 if (x_sign) 1251 res = -Cstar.w[0]; 1252 else 1253 res = Cstar.w[0]; 1254 } else if (exp == 0) { 1255 // 1 <= q <= 19 1256 // res = +/-C (exact) 1257 if (x_sign) 1258 res = -C1.w[0]; 1259 else 1260 res = C1.w[0]; 1261 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 1262 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 1263 if (x_sign) 1264 res = -C1.w[0] * ten2k64[exp]; 1265 else 1266 res = C1.w[0] * ten2k64[exp]; 1267 } 1268 } 1269 } 1270 1271 BID_RETURN (res); 1272 } 1273 1274 /***************************************************************************** 1275 * BID128_to_int64_ceil 1276 ****************************************************************************/ 1277 1278 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_ceil, 1279 x) 1280 1281 SINT64 res; 1282 UINT64 x_sign; 1283 UINT64 x_exp; 1284 int exp; // unbiased exponent 1285 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 1286 BID_UI64DOUBLE tmp1; 1287 unsigned int x_nr_bits; 1288 int q, ind, shift; 1289 UINT128 C1, C; 1290 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 1291 UINT256 fstar; 1292 UINT256 P256; 1293 1294 // unpack x 1295 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 1296 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 1297 C1.w[1] = x.w[1] & MASK_COEFF; 1298 C1.w[0] = x.w[0]; 1299 1300 // check for NaN or Infinity 1301 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 1302 // x is special 1303 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 1304 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 1305 // set invalid flag 1306 *pfpsf |= INVALID_EXCEPTION; 1307 // return Integer Indefinite 1308 res = 0x8000000000000000ull; 1309 } else { // x is QNaN 1310 // set invalid flag 1311 *pfpsf |= INVALID_EXCEPTION; 1312 // return Integer Indefinite 1313 res = 0x8000000000000000ull; 1314 } 1315 BID_RETURN (res); 1316 } else { // x is not a NaN, so it must be infinity 1317 if (!x_sign) { // x is +inf 1318 // set invalid flag 1319 *pfpsf |= INVALID_EXCEPTION; 1320 // return Integer Indefinite 1321 res = 0x8000000000000000ull; 1322 } else { // x is -inf 1323 // set invalid flag 1324 *pfpsf |= INVALID_EXCEPTION; 1325 // return Integer Indefinite 1326 res = 0x8000000000000000ull; 1327 } 1328 BID_RETURN (res); 1329 } 1330 } 1331 // check for non-canonical values (after the check for special values) 1332 if ((C1.w[1] > 0x0001ed09bead87c0ull) 1333 || (C1.w[1] == 0x0001ed09bead87c0ull 1334 && (C1.w[0] > 0x378d8e63ffffffffull)) 1335 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 1336 res = 0x0000000000000000ull; 1337 BID_RETURN (res); 1338 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 1339 // x is 0 1340 res = 0x0000000000000000ull; 1341 BID_RETURN (res); 1342 } else { // x is not special and is not zero 1343 1344 // q = nr. of decimal digits in x 1345 // determine first the nr. of bits in x 1346 if (C1.w[1] == 0) { 1347 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 1348 // split the 64-bit value in two 32-bit halves to avoid rounding errors 1349 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 1350 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 1351 x_nr_bits = 1352 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1353 } else { // x < 2^32 1354 tmp1.d = (double) (C1.w[0]); // exact conversion 1355 x_nr_bits = 1356 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1357 } 1358 } else { // if x < 2^53 1359 tmp1.d = (double) C1.w[0]; // exact conversion 1360 x_nr_bits = 1361 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1362 } 1363 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 1364 tmp1.d = (double) C1.w[1]; // exact conversion 1365 x_nr_bits = 1366 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1367 } 1368 q = nr_digits[x_nr_bits - 1].digits; 1369 if (q == 0) { 1370 q = nr_digits[x_nr_bits - 1].digits1; 1371 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 1372 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 1373 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 1374 q++; 1375 } 1376 exp = (x_exp >> 49) - 6176; 1377 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 1378 // set invalid flag 1379 *pfpsf |= INVALID_EXCEPTION; 1380 // return Integer Indefinite 1381 res = 0x8000000000000000ull; 1382 BID_RETURN (res); 1383 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 1384 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 1385 // so x rounded to an integer may or may not fit in a signed 64-bit int 1386 // the cases that do not fit are identified here; the ones that fit 1387 // fall through and will be handled with other cases further, 1388 // under '1 <= q + exp <= 19' 1389 if (x_sign) { // if n < 0 and q + exp = 19 1390 // if n <= -2^63 - 1 then n is too large 1391 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1 1392 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+2), 1<=q<=34 1393 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x5000000000000000a, 1<=q<=34 1394 C.w[1] = 0x0000000000000005ull; 1395 C.w[0] = 0x000000000000000aull; 1396 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1397 // 10^(20-q) is 64-bit, and so is C1 1398 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1399 } else if (q == 20) { 1400 ; // C1 * 10^0 = C1 1401 } else { // if 21 <= q <= 34 1402 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1403 } 1404 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 1405 // set invalid flag 1406 *pfpsf |= INVALID_EXCEPTION; 1407 // return Integer Indefinite 1408 res = 0x8000000000000000ull; 1409 BID_RETURN (res); 1410 } 1411 // else cases that can be rounded to a 64-bit int fall through 1412 // to '1 <= q + exp <= 19' 1413 } else { // if n > 0 and q + exp = 19 1414 // if n > 2^63 - 1 then n is too large 1415 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1 1416 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 10*(2^63-1), 1<=q<=34 1417 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=34 1418 C.w[1] = 0x0000000000000004ull; 1419 C.w[0] = 0xfffffffffffffff6ull; 1420 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1421 // 10^(20-q) is 64-bit, and so is C1 1422 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1423 } else if (q == 20) { 1424 ; // C1 * 10^0 = C1 1425 } else { // if 21 <= q <= 34 1426 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1427 } 1428 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 1429 // set invalid flag 1430 *pfpsf |= INVALID_EXCEPTION; 1431 // return Integer Indefinite 1432 res = 0x8000000000000000ull; 1433 BID_RETURN (res); 1434 } 1435 // else cases that can be rounded to a 64-bit int fall through 1436 // to '1 <= q + exp <= 19' 1437 } 1438 } 1439 // n is not too large to be converted to int64: -2^63-1 < n <= 2^63 - 1 1440 // Note: some of the cases tested for above fall through to this point 1441 // Restore C1 which may have been modified above 1442 C1.w[1] = x.w[1] & MASK_COEFF; 1443 C1.w[0] = x.w[0]; 1444 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 1445 // return 0 or 1 1446 if (x_sign) 1447 res = 0x0000000000000000ull; 1448 else 1449 res = 0x0000000000000001ull; 1450 BID_RETURN (res); 1451 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 1452 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded 1453 // up to a 64-bit signed integer 1454 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 1455 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 1456 // chop off ind digits from the lower part of C1 1457 // C1 fits in 127 bits 1458 // calculate C* and f* 1459 // C* is actually floor(C*) in this case 1460 // C* and f* need shifting and masking, as shown by 1461 // shiftright128[] and maskhigh128[] 1462 // 1 <= x <= 33 1463 // kx = 10^(-x) = ten2mk128[ind - 1] 1464 // C* = C1 * 10^(-x) 1465 // the approximation of 10^(-x) was rounded up to 118 bits 1466 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 1467 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1468 Cstar.w[1] = P256.w[3]; 1469 Cstar.w[0] = P256.w[2]; 1470 fstar.w[3] = 0; 1471 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 1472 fstar.w[1] = P256.w[1]; 1473 fstar.w[0] = P256.w[0]; 1474 } else { // 22 <= ind - 1 <= 33 1475 Cstar.w[1] = 0; 1476 Cstar.w[0] = P256.w[3]; 1477 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 1478 fstar.w[2] = P256.w[2]; 1479 fstar.w[1] = P256.w[1]; 1480 fstar.w[0] = P256.w[0]; 1481 } 1482 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 1483 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 1484 // C* = floor(C*) (logical right shift; C has p decimal digits, 1485 // correct by Property 1) 1486 // n = C* * 10^(e+x) 1487 1488 // shift right C* by Ex-128 = shiftright128[ind] 1489 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 1490 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1491 Cstar.w[0] = 1492 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 1493 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 1494 } else { // 22 <= ind - 1 <= 33 1495 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 1496 } 1497 // if the result is positive and inexact, need to add 1 to it 1498 1499 // determine inexactness of the rounding of C* 1500 // if (0 < f* < 10^(-x)) then 1501 // the result is exact 1502 // else // if (f* > T*) then 1503 // the result is inexact 1504 if (ind - 1 <= 2) { 1505 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1506 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1507 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1508 if (!x_sign) { // positive and inexact 1509 Cstar.w[0]++; 1510 if (Cstar.w[0] == 0x0) 1511 Cstar.w[1]++; 1512 } 1513 } // else the result is exact 1514 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 1515 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1516 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1517 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1518 if (!x_sign) { // positive and inexact 1519 Cstar.w[0]++; 1520 if (Cstar.w[0] == 0x0) 1521 Cstar.w[1]++; 1522 } 1523 } // else the result is exact 1524 } else { // if 22 <= ind <= 33 1525 if (fstar.w[3] || fstar.w[2] 1526 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1527 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1528 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1529 if (!x_sign) { // positive and inexact 1530 Cstar.w[0]++; 1531 if (Cstar.w[0] == 0x0) 1532 Cstar.w[1]++; 1533 } 1534 } // else the result is exact 1535 } 1536 if (x_sign) 1537 res = -Cstar.w[0]; 1538 else 1539 res = Cstar.w[0]; 1540 } else if (exp == 0) { 1541 // 1 <= q <= 19 1542 // res = +/-C (exact) 1543 if (x_sign) 1544 res = -C1.w[0]; 1545 else 1546 res = C1.w[0]; 1547 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 1548 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 1549 if (x_sign) 1550 res = -C1.w[0] * ten2k64[exp]; 1551 else 1552 res = C1.w[0] * ten2k64[exp]; 1553 } 1554 } 1555 } 1556 1557 BID_RETURN (res); 1558 } 1559 1560 /***************************************************************************** 1561 * BID128_to_int64_xceil 1562 ****************************************************************************/ 1563 1564 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_xceil, 1565 x) 1566 1567 SINT64 res; 1568 UINT64 x_sign; 1569 UINT64 x_exp; 1570 int exp; // unbiased exponent 1571 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 1572 BID_UI64DOUBLE tmp1; 1573 unsigned int x_nr_bits; 1574 int q, ind, shift; 1575 UINT128 C1, C; 1576 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 1577 UINT256 fstar; 1578 UINT256 P256; 1579 1580 // unpack x 1581 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 1582 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 1583 C1.w[1] = x.w[1] & MASK_COEFF; 1584 C1.w[0] = x.w[0]; 1585 1586 // check for NaN or Infinity 1587 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 1588 // x is special 1589 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 1590 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 1591 // set invalid flag 1592 *pfpsf |= INVALID_EXCEPTION; 1593 // return Integer Indefinite 1594 res = 0x8000000000000000ull; 1595 } else { // x is QNaN 1596 // set invalid flag 1597 *pfpsf |= INVALID_EXCEPTION; 1598 // return Integer Indefinite 1599 res = 0x8000000000000000ull; 1600 } 1601 BID_RETURN (res); 1602 } else { // x is not a NaN, so it must be infinity 1603 if (!x_sign) { // x is +inf 1604 // set invalid flag 1605 *pfpsf |= INVALID_EXCEPTION; 1606 // return Integer Indefinite 1607 res = 0x8000000000000000ull; 1608 } else { // x is -inf 1609 // set invalid flag 1610 *pfpsf |= INVALID_EXCEPTION; 1611 // return Integer Indefinite 1612 res = 0x8000000000000000ull; 1613 } 1614 BID_RETURN (res); 1615 } 1616 } 1617 // check for non-canonical values (after the check for special values) 1618 if ((C1.w[1] > 0x0001ed09bead87c0ull) 1619 || (C1.w[1] == 0x0001ed09bead87c0ull 1620 && (C1.w[0] > 0x378d8e63ffffffffull)) 1621 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 1622 res = 0x0000000000000000ull; 1623 BID_RETURN (res); 1624 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 1625 // x is 0 1626 res = 0x0000000000000000ull; 1627 BID_RETURN (res); 1628 } else { // x is not special and is not zero 1629 1630 // q = nr. of decimal digits in x 1631 // determine first the nr. of bits in x 1632 if (C1.w[1] == 0) { 1633 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 1634 // split the 64-bit value in two 32-bit halves to avoid rounding errors 1635 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 1636 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 1637 x_nr_bits = 1638 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1639 } else { // x < 2^32 1640 tmp1.d = (double) (C1.w[0]); // exact conversion 1641 x_nr_bits = 1642 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1643 } 1644 } else { // if x < 2^53 1645 tmp1.d = (double) C1.w[0]; // exact conversion 1646 x_nr_bits = 1647 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1648 } 1649 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 1650 tmp1.d = (double) C1.w[1]; // exact conversion 1651 x_nr_bits = 1652 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1653 } 1654 q = nr_digits[x_nr_bits - 1].digits; 1655 if (q == 0) { 1656 q = nr_digits[x_nr_bits - 1].digits1; 1657 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 1658 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 1659 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 1660 q++; 1661 } 1662 exp = (x_exp >> 49) - 6176; 1663 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 1664 // set invalid flag 1665 *pfpsf |= INVALID_EXCEPTION; 1666 // return Integer Indefinite 1667 res = 0x8000000000000000ull; 1668 BID_RETURN (res); 1669 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 1670 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 1671 // so x rounded to an integer may or may not fit in a signed 64-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 <= 19' 1675 if (x_sign) { // if n < 0 and q + exp = 19 1676 // if n <= -2^63 - 1 then n is too large 1677 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1 1678 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+2), 1<=q<=34 1679 // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x5000000000000000a, 1<=q<=34 1680 C.w[1] = 0x0000000000000005ull; 1681 C.w[0] = 0x000000000000000aull; 1682 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1683 // 10^(20-q) is 64-bit, and so is C1 1684 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1685 } else if (q == 20) { 1686 ; // C1 * 10^0 = C1 1687 } else { // if 21 <= q <= 34 1688 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1689 } 1690 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 1691 // set invalid flag 1692 *pfpsf |= INVALID_EXCEPTION; 1693 // return Integer Indefinite 1694 res = 0x8000000000000000ull; 1695 BID_RETURN (res); 1696 } 1697 // else cases that can be rounded to a 64-bit int fall through 1698 // to '1 <= q + exp <= 19' 1699 } else { // if n > 0 and q + exp = 19 1700 // if n > 2^63 - 1 then n is too large 1701 // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1 1702 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 10*(2^63-1), 1<=q<=34 1703 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=34 1704 C.w[1] = 0x0000000000000004ull; 1705 C.w[0] = 0xfffffffffffffff6ull; 1706 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1707 // 10^(20-q) is 64-bit, and so is C1 1708 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1709 } else if (q == 20) { 1710 ; // C1 * 10^0 = C1 1711 } else { // if 21 <= q <= 34 1712 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1713 } 1714 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) { 1715 // set invalid flag 1716 *pfpsf |= INVALID_EXCEPTION; 1717 // return Integer Indefinite 1718 res = 0x8000000000000000ull; 1719 BID_RETURN (res); 1720 } 1721 // else cases that can be rounded to a 64-bit int fall through 1722 // to '1 <= q + exp <= 19' 1723 } 1724 } 1725 // n is not too large to be converted to int64: -2^63-1 < n <= 2^63 - 1 1726 // Note: some of the cases tested for above fall through to this point 1727 // Restore C1 which may have been modified above 1728 C1.w[1] = x.w[1] & MASK_COEFF; 1729 C1.w[0] = x.w[0]; 1730 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 1731 // set inexact flag 1732 *pfpsf |= INEXACT_EXCEPTION; 1733 // return 0 or 1 1734 if (x_sign) 1735 res = 0x0000000000000000ull; 1736 else 1737 res = 0x0000000000000001ull; 1738 BID_RETURN (res); 1739 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 1740 // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded 1741 // up to a 64-bit signed integer 1742 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 1743 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 1744 // chop off ind digits from the lower part of C1 1745 // C1 fits in 127 bits 1746 // calculate C* and f* 1747 // C* is actually floor(C*) in this case 1748 // C* and f* need shifting and masking, as shown by 1749 // shiftright128[] and maskhigh128[] 1750 // 1 <= x <= 33 1751 // kx = 10^(-x) = ten2mk128[ind - 1] 1752 // C* = C1 * 10^(-x) 1753 // the approximation of 10^(-x) was rounded up to 118 bits 1754 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 1755 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1756 Cstar.w[1] = P256.w[3]; 1757 Cstar.w[0] = P256.w[2]; 1758 fstar.w[3] = 0; 1759 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 1760 fstar.w[1] = P256.w[1]; 1761 fstar.w[0] = P256.w[0]; 1762 } else { // 22 <= ind - 1 <= 33 1763 Cstar.w[1] = 0; 1764 Cstar.w[0] = P256.w[3]; 1765 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 1766 fstar.w[2] = P256.w[2]; 1767 fstar.w[1] = P256.w[1]; 1768 fstar.w[0] = P256.w[0]; 1769 } 1770 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 1771 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 1772 // C* = floor(C*) (logical right shift; C has p decimal digits, 1773 // correct by Property 1) 1774 // n = C* * 10^(e+x) 1775 1776 // shift right C* by Ex-128 = shiftright128[ind] 1777 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 1778 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 1779 Cstar.w[0] = 1780 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 1781 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 1782 } else { // 22 <= ind - 1 <= 33 1783 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 1784 } 1785 // if the result is positive and inexact, need to add 1 to it 1786 1787 // determine inexactness of the rounding of C* 1788 // if (0 < f* < 10^(-x)) then 1789 // the result is exact 1790 // else // if (f* > T*) then 1791 // the result is inexact 1792 if (ind - 1 <= 2) { 1793 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1794 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1795 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1796 if (!x_sign) { // positive and inexact 1797 Cstar.w[0]++; 1798 if (Cstar.w[0] == 0x0) 1799 Cstar.w[1]++; 1800 } 1801 // set the inexact flag 1802 *pfpsf |= INEXACT_EXCEPTION; 1803 } // else the result is exact 1804 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 1805 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1806 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1807 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1808 if (!x_sign) { // positive and inexact 1809 Cstar.w[0]++; 1810 if (Cstar.w[0] == 0x0) 1811 Cstar.w[1]++; 1812 } 1813 // set the inexact flag 1814 *pfpsf |= INEXACT_EXCEPTION; 1815 } // else the result is exact 1816 } else { // if 22 <= ind <= 33 1817 if (fstar.w[3] || fstar.w[2] 1818 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 1819 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 1820 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 1821 if (!x_sign) { // positive and inexact 1822 Cstar.w[0]++; 1823 if (Cstar.w[0] == 0x0) 1824 Cstar.w[1]++; 1825 } 1826 // set the inexact flag 1827 *pfpsf |= INEXACT_EXCEPTION; 1828 } // else the result is exact 1829 } 1830 1831 if (x_sign) 1832 res = -Cstar.w[0]; 1833 else 1834 res = Cstar.w[0]; 1835 } else if (exp == 0) { 1836 // 1 <= q <= 19 1837 // res = +/-C (exact) 1838 if (x_sign) 1839 res = -C1.w[0]; 1840 else 1841 res = C1.w[0]; 1842 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 1843 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 1844 if (x_sign) 1845 res = -C1.w[0] * ten2k64[exp]; 1846 else 1847 res = C1.w[0] * ten2k64[exp]; 1848 } 1849 } 1850 } 1851 1852 BID_RETURN (res); 1853 } 1854 1855 /***************************************************************************** 1856 * BID128_to_int64_int 1857 ****************************************************************************/ 1858 1859 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_int, 1860 x) 1861 1862 SINT64 res; 1863 UINT64 x_sign; 1864 UINT64 x_exp; 1865 int exp; // unbiased exponent 1866 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 1867 BID_UI64DOUBLE tmp1; 1868 unsigned int x_nr_bits; 1869 int q, ind, shift; 1870 UINT128 C1, C; 1871 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 1872 UINT256 P256; 1873 1874 // unpack x 1875 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 1876 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 1877 C1.w[1] = x.w[1] & MASK_COEFF; 1878 C1.w[0] = x.w[0]; 1879 1880 // check for NaN or Infinity 1881 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 1882 // x is special 1883 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 1884 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 1885 // set invalid flag 1886 *pfpsf |= INVALID_EXCEPTION; 1887 // return Integer Indefinite 1888 res = 0x8000000000000000ull; 1889 } else { // x is QNaN 1890 // set invalid flag 1891 *pfpsf |= INVALID_EXCEPTION; 1892 // return Integer Indefinite 1893 res = 0x8000000000000000ull; 1894 } 1895 BID_RETURN (res); 1896 } else { // x is not a NaN, so it must be infinity 1897 if (!x_sign) { // x is +inf 1898 // set invalid flag 1899 *pfpsf |= INVALID_EXCEPTION; 1900 // return Integer Indefinite 1901 res = 0x8000000000000000ull; 1902 } else { // x is -inf 1903 // set invalid flag 1904 *pfpsf |= INVALID_EXCEPTION; 1905 // return Integer Indefinite 1906 res = 0x8000000000000000ull; 1907 } 1908 BID_RETURN (res); 1909 } 1910 } 1911 // check for non-canonical values (after the check for special values) 1912 if ((C1.w[1] > 0x0001ed09bead87c0ull) 1913 || (C1.w[1] == 0x0001ed09bead87c0ull 1914 && (C1.w[0] > 0x378d8e63ffffffffull)) 1915 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 1916 res = 0x0000000000000000ull; 1917 BID_RETURN (res); 1918 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 1919 // x is 0 1920 res = 0x0000000000000000ull; 1921 BID_RETURN (res); 1922 } else { // x is not special and is not zero 1923 1924 // q = nr. of decimal digits in x 1925 // determine first the nr. of bits in x 1926 if (C1.w[1] == 0) { 1927 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 1928 // split the 64-bit value in two 32-bit halves to avoid rounding errors 1929 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 1930 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 1931 x_nr_bits = 1932 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1933 } else { // x < 2^32 1934 tmp1.d = (double) (C1.w[0]); // exact conversion 1935 x_nr_bits = 1936 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1937 } 1938 } else { // if x < 2^53 1939 tmp1.d = (double) C1.w[0]; // exact conversion 1940 x_nr_bits = 1941 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1942 } 1943 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 1944 tmp1.d = (double) C1.w[1]; // exact conversion 1945 x_nr_bits = 1946 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 1947 } 1948 q = nr_digits[x_nr_bits - 1].digits; 1949 if (q == 0) { 1950 q = nr_digits[x_nr_bits - 1].digits1; 1951 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 1952 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 1953 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 1954 q++; 1955 } 1956 exp = (x_exp >> 49) - 6176; 1957 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 1958 // set invalid flag 1959 *pfpsf |= INVALID_EXCEPTION; 1960 // return Integer Indefinite 1961 res = 0x8000000000000000ull; 1962 BID_RETURN (res); 1963 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 1964 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 1965 // so x rounded to an integer may or may not fit in a signed 64-bit int 1966 // the cases that do not fit are identified here; the ones that fit 1967 // fall through and will be handled with other cases further, 1968 // under '1 <= q + exp <= 19' 1969 if (x_sign) { // if n < 0 and q + exp = 19 1970 // if n <= -2^63 - 1 then n is too large 1971 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1 1972 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=34 1973 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=34 1974 C.w[1] = 0x0000000000000005ull; 1975 C.w[0] = 0x000000000000000aull; 1976 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 1977 // 10^(20-q) is 64-bit, and so is C1 1978 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 1979 } else if (q == 20) { 1980 ; // C1 * 10^0 = C1 1981 } else { // if 21 <= q <= 34 1982 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 1983 } 1984 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 1985 // set invalid flag 1986 *pfpsf |= INVALID_EXCEPTION; 1987 // return Integer Indefinite 1988 res = 0x8000000000000000ull; 1989 BID_RETURN (res); 1990 } 1991 // else cases that can be rounded to a 64-bit int fall through 1992 // to '1 <= q + exp <= 19' 1993 } else { // if n > 0 and q + exp = 19 1994 // if n >= 2^63 then n is too large 1995 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63 1996 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34 1997 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34 1998 C.w[1] = 0x0000000000000005ull; 1999 C.w[0] = 0x0000000000000000ull; 2000 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2001 // 10^(20-q) is 64-bit, and so is C1 2002 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2003 } else if (q == 20) { 2004 ; // C1 * 10^0 = C1 2005 } else { // if 21 <= q <= 34 2006 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2007 } 2008 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2009 // set invalid flag 2010 *pfpsf |= INVALID_EXCEPTION; 2011 // return Integer Indefinite 2012 res = 0x8000000000000000ull; 2013 BID_RETURN (res); 2014 } 2015 // else cases that can be rounded to a 64-bit int fall through 2016 // to '1 <= q + exp <= 19' 2017 } 2018 } 2019 // n is not too large to be converted to int64: -2^63-1 < n < 2^63 2020 // Note: some of the cases tested for above fall through to this point 2021 // Restore C1 which may have been modified above 2022 C1.w[1] = x.w[1] & MASK_COEFF; 2023 C1.w[0] = x.w[0]; 2024 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 2025 // return 0 2026 res = 0x0000000000000000ull; 2027 BID_RETURN (res); 2028 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 2029 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded 2030 // toward zero to a 64-bit signed integer 2031 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 2032 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 2033 // chop off ind digits from the lower part of C1 2034 // C1 fits in 127 bits 2035 // calculate C* and f* 2036 // C* is actually floor(C*) in this case 2037 // C* and f* need shifting and masking, as shown by 2038 // shiftright128[] and maskhigh128[] 2039 // 1 <= x <= 33 2040 // kx = 10^(-x) = ten2mk128[ind - 1] 2041 // C* = C1 * 10^(-x) 2042 // the approximation of 10^(-x) was rounded up to 118 bits 2043 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 2044 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2045 Cstar.w[1] = P256.w[3]; 2046 Cstar.w[0] = P256.w[2]; 2047 } else { // 22 <= ind - 1 <= 33 2048 Cstar.w[1] = 0; 2049 Cstar.w[0] = P256.w[3]; 2050 } 2051 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 2052 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 2053 // C* = floor(C*) (logical right shift; C has p decimal digits, 2054 // correct by Property 1) 2055 // n = C* * 10^(e+x) 2056 2057 // shift right C* by Ex-128 = shiftright128[ind] 2058 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 2059 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2060 Cstar.w[0] = 2061 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 2062 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 2063 } else { // 22 <= ind - 1 <= 33 2064 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 2065 } 2066 if (x_sign) 2067 res = -Cstar.w[0]; 2068 else 2069 res = Cstar.w[0]; 2070 } else if (exp == 0) { 2071 // 1 <= q <= 19 2072 // res = +/-C (exact) 2073 if (x_sign) 2074 res = -C1.w[0]; 2075 else 2076 res = C1.w[0]; 2077 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 2078 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 2079 if (x_sign) 2080 res = -C1.w[0] * ten2k64[exp]; 2081 else 2082 res = C1.w[0] * ten2k64[exp]; 2083 } 2084 } 2085 } 2086 2087 BID_RETURN (res); 2088 } 2089 2090 /***************************************************************************** 2091 * BID128_to_xint64_xint 2092 ****************************************************************************/ 2093 2094 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, bid128_to_int64_xint, 2095 x) 2096 2097 SINT64 res; 2098 UINT64 x_sign; 2099 UINT64 x_exp; 2100 int exp; // unbiased exponent 2101 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 2102 BID_UI64DOUBLE tmp1; 2103 unsigned int x_nr_bits; 2104 int q, ind, shift; 2105 UINT128 C1, C; 2106 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 2107 UINT256 fstar; 2108 UINT256 P256; 2109 2110 // unpack x 2111 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 2112 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 2113 C1.w[1] = x.w[1] & MASK_COEFF; 2114 C1.w[0] = x.w[0]; 2115 2116 // check for NaN or Infinity 2117 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 2118 // x is special 2119 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 2120 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 2121 // set invalid flag 2122 *pfpsf |= INVALID_EXCEPTION; 2123 // return Integer Indefinite 2124 res = 0x8000000000000000ull; 2125 } else { // x is QNaN 2126 // set invalid flag 2127 *pfpsf |= INVALID_EXCEPTION; 2128 // return Integer Indefinite 2129 res = 0x8000000000000000ull; 2130 } 2131 BID_RETURN (res); 2132 } else { // x is not a NaN, so it must be infinity 2133 if (!x_sign) { // x is +inf 2134 // set invalid flag 2135 *pfpsf |= INVALID_EXCEPTION; 2136 // return Integer Indefinite 2137 res = 0x8000000000000000ull; 2138 } else { // x is -inf 2139 // set invalid flag 2140 *pfpsf |= INVALID_EXCEPTION; 2141 // return Integer Indefinite 2142 res = 0x8000000000000000ull; 2143 } 2144 BID_RETURN (res); 2145 } 2146 } 2147 // check for non-canonical values (after the check for special values) 2148 if ((C1.w[1] > 0x0001ed09bead87c0ull) 2149 || (C1.w[1] == 0x0001ed09bead87c0ull 2150 && (C1.w[0] > 0x378d8e63ffffffffull)) 2151 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 2152 res = 0x0000000000000000ull; 2153 BID_RETURN (res); 2154 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 2155 // x is 0 2156 res = 0x0000000000000000ull; 2157 BID_RETURN (res); 2158 } else { // x is not special and is not zero 2159 2160 // q = nr. of decimal digits in x 2161 // determine first the nr. of bits in x 2162 if (C1.w[1] == 0) { 2163 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 2164 // split the 64-bit value in two 32-bit halves to avoid rounding errors 2165 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 2166 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 2167 x_nr_bits = 2168 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2169 } else { // x < 2^32 2170 tmp1.d = (double) (C1.w[0]); // exact conversion 2171 x_nr_bits = 2172 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2173 } 2174 } else { // if x < 2^53 2175 tmp1.d = (double) C1.w[0]; // exact conversion 2176 x_nr_bits = 2177 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2178 } 2179 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 2180 tmp1.d = (double) C1.w[1]; // exact conversion 2181 x_nr_bits = 2182 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2183 } 2184 q = nr_digits[x_nr_bits - 1].digits; 2185 if (q == 0) { 2186 q = nr_digits[x_nr_bits - 1].digits1; 2187 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 2188 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 2189 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 2190 q++; 2191 } 2192 exp = (x_exp >> 49) - 6176; 2193 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 2194 // set invalid flag 2195 *pfpsf |= INVALID_EXCEPTION; 2196 // return Integer Indefinite 2197 res = 0x8000000000000000ull; 2198 BID_RETURN (res); 2199 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 2200 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 2201 // so x rounded to an integer may or may not fit in a signed 64-bit int 2202 // the cases that do not fit are identified here; the ones that fit 2203 // fall through and will be handled with other cases further, 2204 // under '1 <= q + exp <= 19' 2205 if (x_sign) { // if n < 0 and q + exp = 19 2206 // if n <= -2^63 - 1 then n is too large 2207 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1 2208 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=34 2209 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=34 2210 C.w[1] = 0x0000000000000005ull; 2211 C.w[0] = 0x000000000000000aull; 2212 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2213 // 10^(20-q) is 64-bit, and so is C1 2214 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2215 } else if (q == 20) { 2216 ; // C1 * 10^0 = C1 2217 } else { // if 21 <= q <= 34 2218 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2219 } 2220 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2221 // set invalid flag 2222 *pfpsf |= INVALID_EXCEPTION; 2223 // return Integer Indefinite 2224 res = 0x8000000000000000ull; 2225 BID_RETURN (res); 2226 } 2227 // else cases that can be rounded to a 64-bit int fall through 2228 // to '1 <= q + exp <= 19' 2229 } else { // if n > 0 and q + exp = 19 2230 // if n >= 2^63 then n is too large 2231 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63 2232 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=34 2233 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=34 2234 C.w[1] = 0x0000000000000005ull; 2235 C.w[0] = 0x0000000000000000ull; 2236 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2237 // 10^(20-q) is 64-bit, and so is C1 2238 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2239 } else if (q == 20) { 2240 ; // C1 * 10^0 = C1 2241 } else { // if 21 <= q <= 34 2242 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2243 } 2244 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2245 // set invalid flag 2246 *pfpsf |= INVALID_EXCEPTION; 2247 // return Integer Indefinite 2248 res = 0x8000000000000000ull; 2249 BID_RETURN (res); 2250 } 2251 // else cases that can be rounded to a 64-bit int fall through 2252 // to '1 <= q + exp <= 19' 2253 } 2254 } 2255 // n is not too large to be converted to int64: -2^63-1 < n < 2^63 2256 // Note: some of the cases tested for above fall through to this point 2257 // Restore C1 which may have been modified above 2258 C1.w[1] = x.w[1] & MASK_COEFF; 2259 C1.w[0] = x.w[0]; 2260 if ((q + exp) <= 0) { // n = +/-0.[0...0]c(0)c(1)...c(q-1) 2261 // set inexact flag 2262 *pfpsf |= INEXACT_EXCEPTION; 2263 // return 0 2264 res = 0x0000000000000000ull; 2265 BID_RETURN (res); 2266 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 2267 // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded 2268 // toward zero to a 64-bit signed integer 2269 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 2270 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 2271 // chop off ind digits from the lower part of C1 2272 // C1 fits in 127 bits 2273 // calculate C* and f* 2274 // C* is actually floor(C*) in this case 2275 // C* and f* need shifting and masking, as shown by 2276 // shiftright128[] and maskhigh128[] 2277 // 1 <= x <= 33 2278 // kx = 10^(-x) = ten2mk128[ind - 1] 2279 // C* = C1 * 10^(-x) 2280 // the approximation of 10^(-x) was rounded up to 118 bits 2281 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 2282 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2283 Cstar.w[1] = P256.w[3]; 2284 Cstar.w[0] = P256.w[2]; 2285 fstar.w[3] = 0; 2286 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 2287 fstar.w[1] = P256.w[1]; 2288 fstar.w[0] = P256.w[0]; 2289 } else { // 22 <= ind - 1 <= 33 2290 Cstar.w[1] = 0; 2291 Cstar.w[0] = P256.w[3]; 2292 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 2293 fstar.w[2] = P256.w[2]; 2294 fstar.w[1] = P256.w[1]; 2295 fstar.w[0] = P256.w[0]; 2296 } 2297 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 2298 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 2299 // C* = floor(C*) (logical right shift; C has p decimal digits, 2300 // correct by Property 1) 2301 // n = C* * 10^(e+x) 2302 2303 // shift right C* by Ex-128 = shiftright128[ind] 2304 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 2305 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2306 Cstar.w[0] = 2307 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 2308 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 2309 } else { // 22 <= ind - 1 <= 33 2310 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 2311 } 2312 // determine inexactness of the rounding of C* 2313 // if (0 < f* < 10^(-x)) then 2314 // the result is exact 2315 // else // if (f* > T*) then 2316 // the result is inexact 2317 if (ind - 1 <= 2) { 2318 if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 2319 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 2320 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 2321 // set the inexact flag 2322 *pfpsf |= INEXACT_EXCEPTION; 2323 } // else the result is exact 2324 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 2325 if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 2326 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 2327 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 2328 // set the inexact flag 2329 *pfpsf |= INEXACT_EXCEPTION; 2330 } 2331 } else { // if 22 <= ind <= 33 2332 if (fstar.w[3] || fstar.w[2] 2333 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 2334 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 2335 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 2336 // set the inexact flag 2337 *pfpsf |= INEXACT_EXCEPTION; 2338 } 2339 } 2340 2341 if (x_sign) 2342 res = -Cstar.w[0]; 2343 else 2344 res = Cstar.w[0]; 2345 } else if (exp == 0) { 2346 // 1 <= q <= 19 2347 // res = +/-C (exact) 2348 if (x_sign) 2349 res = -C1.w[0]; 2350 else 2351 res = C1.w[0]; 2352 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 2353 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 2354 if (x_sign) 2355 res = -C1.w[0] * ten2k64[exp]; 2356 else 2357 res = C1.w[0] * ten2k64[exp]; 2358 } 2359 } 2360 } 2361 2362 BID_RETURN (res); 2363 } 2364 2365 /***************************************************************************** 2366 * BID128_to_int64_rninta 2367 ****************************************************************************/ 2368 2369 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, 2370 bid128_to_int64_rninta, x) 2371 2372 SINT64 res; 2373 UINT64 x_sign; 2374 UINT64 x_exp; 2375 int exp; // unbiased exponent 2376 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 2377 UINT64 tmp64; 2378 BID_UI64DOUBLE tmp1; 2379 unsigned int x_nr_bits; 2380 int q, ind, shift; 2381 UINT128 C1, C; 2382 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 2383 UINT256 P256; 2384 2385 // unpack x 2386 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 2387 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 2388 C1.w[1] = x.w[1] & MASK_COEFF; 2389 C1.w[0] = x.w[0]; 2390 2391 // check for NaN or Infinity 2392 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 2393 // x is special 2394 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 2395 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 2396 // set invalid flag 2397 *pfpsf |= INVALID_EXCEPTION; 2398 // return Integer Indefinite 2399 res = 0x8000000000000000ull; 2400 } else { // x is QNaN 2401 // set invalid flag 2402 *pfpsf |= INVALID_EXCEPTION; 2403 // return Integer Indefinite 2404 res = 0x8000000000000000ull; 2405 } 2406 BID_RETURN (res); 2407 } else { // x is not a NaN, so it must be infinity 2408 if (!x_sign) { // x is +inf 2409 // set invalid flag 2410 *pfpsf |= INVALID_EXCEPTION; 2411 // return Integer Indefinite 2412 res = 0x8000000000000000ull; 2413 } else { // x is -inf 2414 // set invalid flag 2415 *pfpsf |= INVALID_EXCEPTION; 2416 // return Integer Indefinite 2417 res = 0x8000000000000000ull; 2418 } 2419 BID_RETURN (res); 2420 } 2421 } 2422 // check for non-canonical values (after the check for special values) 2423 if ((C1.w[1] > 0x0001ed09bead87c0ull) 2424 || (C1.w[1] == 0x0001ed09bead87c0ull 2425 && (C1.w[0] > 0x378d8e63ffffffffull)) 2426 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 2427 res = 0x0000000000000000ull; 2428 BID_RETURN (res); 2429 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 2430 // x is 0 2431 res = 0x0000000000000000ull; 2432 BID_RETURN (res); 2433 } else { // x is not special and is not zero 2434 2435 // q = nr. of decimal digits in x 2436 // determine first the nr. of bits in x 2437 if (C1.w[1] == 0) { 2438 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 2439 // split the 64-bit value in two 32-bit halves to avoid rounding errors 2440 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 2441 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 2442 x_nr_bits = 2443 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2444 } else { // x < 2^32 2445 tmp1.d = (double) (C1.w[0]); // exact conversion 2446 x_nr_bits = 2447 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2448 } 2449 } else { // if x < 2^53 2450 tmp1.d = (double) C1.w[0]; // exact conversion 2451 x_nr_bits = 2452 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2453 } 2454 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 2455 tmp1.d = (double) C1.w[1]; // exact conversion 2456 x_nr_bits = 2457 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2458 } 2459 q = nr_digits[x_nr_bits - 1].digits; 2460 if (q == 0) { 2461 q = nr_digits[x_nr_bits - 1].digits1; 2462 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 2463 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 2464 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 2465 q++; 2466 } 2467 exp = (x_exp >> 49) - 6176; 2468 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 2469 // set invalid flag 2470 *pfpsf |= INVALID_EXCEPTION; 2471 // return Integer Indefinite 2472 res = 0x8000000000000000ull; 2473 BID_RETURN (res); 2474 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 2475 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 2476 // so x rounded to an integer may or may not fit in a signed 64-bit int 2477 // the cases that do not fit are identified here; the ones that fit 2478 // fall through and will be handled with other cases further, 2479 // under '1 <= q + exp <= 19' 2480 if (x_sign) { // if n < 0 and q + exp = 19 2481 // if n <= -2^63 - 1/2 then n is too large 2482 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2 2483 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=34 2484 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=34 2485 C.w[1] = 0x0000000000000005ull; 2486 C.w[0] = 0000000000000005ull; 2487 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2488 // 10^(20-q) is 64-bit, and so is C1 2489 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2490 } else if (q == 20) { 2491 ; // C1 * 10^0 = C1 2492 } else { // if 21 <= q <= 34 2493 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2494 } 2495 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2496 // set invalid flag 2497 *pfpsf |= INVALID_EXCEPTION; 2498 // return Integer Indefinite 2499 res = 0x8000000000000000ull; 2500 BID_RETURN (res); 2501 } 2502 // else cases that can be rounded to a 64-bit int fall through 2503 // to '1 <= q + exp <= 19' 2504 } else { // if n > 0 and q + exp = 19 2505 // if n >= 2^63 - 1/2 then n is too large 2506 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2 2507 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34 2508 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34 2509 C.w[1] = 0x0000000000000004ull; 2510 C.w[0] = 0xfffffffffffffffbull; 2511 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2512 // 10^(20-q) is 64-bit, and so is C1 2513 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2514 } else if (q == 20) { 2515 ; // C1 * 10^0 = C1 2516 } else { // if 21 <= q <= 34 2517 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2518 } 2519 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2520 // set invalid flag 2521 *pfpsf |= INVALID_EXCEPTION; 2522 // return Integer Indefinite 2523 res = 0x8000000000000000ull; 2524 BID_RETURN (res); 2525 } 2526 // else cases that can be rounded to a 64-bit int fall through 2527 // to '1 <= q + exp <= 19' 2528 } 2529 } 2530 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2 2531 // Note: some of the cases tested for above fall through to this point 2532 // Restore C1 which may have been modified above 2533 C1.w[1] = x.w[1] & MASK_COEFF; 2534 C1.w[0] = x.w[0]; 2535 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1) 2536 // return 0 2537 res = 0x0000000000000000ull; 2538 BID_RETURN (res); 2539 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1) 2540 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1) 2541 // res = 0 2542 // else 2543 // res = +/-1 2544 ind = q - 1; 2545 if (ind <= 18) { // 0 <= ind <= 18 2546 if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) { 2547 res = 0x0000000000000000ull; // return 0 2548 } else if (x_sign) { // n < 0 2549 res = 0xffffffffffffffffull; // return -1 2550 } else { // n > 0 2551 res = 0x0000000000000001ull; // return +1 2552 } 2553 } else { // 19 <= ind <= 33 2554 if ((C1.w[1] < midpoint128[ind - 19].w[1]) 2555 || ((C1.w[1] == midpoint128[ind - 19].w[1]) 2556 && (C1.w[0] < midpoint128[ind - 19].w[0]))) { 2557 res = 0x0000000000000000ull; // return 0 2558 } else if (x_sign) { // n < 0 2559 res = 0xffffffffffffffffull; // return -1 2560 } else { // n > 0 2561 res = 0x0000000000000001ull; // return +1 2562 } 2563 } 2564 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 2565 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded 2566 // to nearest to a 64-bit signed integer 2567 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 2568 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 2569 // chop off ind digits from the lower part of C1 2570 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits 2571 tmp64 = C1.w[0]; 2572 if (ind <= 19) { 2573 C1.w[0] = C1.w[0] + midpoint64[ind - 1]; 2574 } else { 2575 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0]; 2576 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1]; 2577 } 2578 if (C1.w[0] < tmp64) 2579 C1.w[1]++; 2580 // calculate C* and f* 2581 // C* is actually floor(C*) in this case 2582 // C* and f* need shifting and masking, as shown by 2583 // shiftright128[] and maskhigh128[] 2584 // 1 <= x <= 33 2585 // kx = 10^(-x) = ten2mk128[ind - 1] 2586 // C* = (C1 + 1/2 * 10^x) * 10^(-x) 2587 // the approximation of 10^(-x) was rounded up to 118 bits 2588 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 2589 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2590 Cstar.w[1] = P256.w[3]; 2591 Cstar.w[0] = P256.w[2]; 2592 } else { // 22 <= ind - 1 <= 33 2593 Cstar.w[1] = 0; 2594 Cstar.w[0] = P256.w[3]; 2595 } 2596 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 2597 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 2598 // if (0 < f* < 10^(-x)) then the result is a midpoint 2599 // if floor(C*) is even then C* = floor(C*) - logical right 2600 // shift; C* has p decimal digits, correct by Prop. 1) 2601 // else if floor(C*) is odd C* = floor(C*)-1 (logical right 2602 // shift; C* has p decimal digits, correct by Pr. 1) 2603 // else 2604 // C* = floor(C*) (logical right shift; C has p decimal digits, 2605 // correct by Property 1) 2606 // n = C* * 10^(e+x) 2607 2608 // shift right C* by Ex-128 = shiftright128[ind] 2609 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 2610 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2611 Cstar.w[0] = 2612 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 2613 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 2614 } else { // 22 <= ind - 1 <= 33 2615 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 2616 } 2617 2618 // if the result was a midpoint it was rounded away from zero 2619 if (x_sign) 2620 res = -Cstar.w[0]; 2621 else 2622 res = Cstar.w[0]; 2623 } else if (exp == 0) { 2624 // 1 <= q <= 19 2625 // res = +/-C (exact) 2626 if (x_sign) 2627 res = -C1.w[0]; 2628 else 2629 res = C1.w[0]; 2630 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 2631 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 2632 if (x_sign) 2633 res = -C1.w[0] * ten2k64[exp]; 2634 else 2635 res = C1.w[0] * ten2k64[exp]; 2636 } 2637 } 2638 } 2639 2640 BID_RETURN (res); 2641 } 2642 2643 /***************************************************************************** 2644 * BID128_to_int64_xrninta 2645 ****************************************************************************/ 2646 2647 BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (SINT64, 2648 bid128_to_int64_xrninta, x) 2649 2650 SINT64 res; 2651 UINT64 x_sign; 2652 UINT64 x_exp; 2653 int exp; // unbiased exponent 2654 // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64) 2655 UINT64 tmp64, tmp64A; 2656 BID_UI64DOUBLE tmp1; 2657 unsigned int x_nr_bits; 2658 int q, ind, shift; 2659 UINT128 C1, C; 2660 UINT128 Cstar; // C* represents up to 34 decimal digits ~ 113 bits 2661 UINT256 fstar; 2662 UINT256 P256; 2663 2664 // unpack x 2665 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative 2666 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 2667 C1.w[1] = x.w[1] & MASK_COEFF; 2668 C1.w[0] = x.w[0]; 2669 2670 // check for NaN or Infinity 2671 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 2672 // x is special 2673 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN 2674 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN 2675 // set invalid flag 2676 *pfpsf |= INVALID_EXCEPTION; 2677 // return Integer Indefinite 2678 res = 0x8000000000000000ull; 2679 } else { // x is QNaN 2680 // set invalid flag 2681 *pfpsf |= INVALID_EXCEPTION; 2682 // return Integer Indefinite 2683 res = 0x8000000000000000ull; 2684 } 2685 BID_RETURN (res); 2686 } else { // x is not a NaN, so it must be infinity 2687 if (!x_sign) { // x is +inf 2688 // set invalid flag 2689 *pfpsf |= INVALID_EXCEPTION; 2690 // return Integer Indefinite 2691 res = 0x8000000000000000ull; 2692 } else { // x is -inf 2693 // set invalid flag 2694 *pfpsf |= INVALID_EXCEPTION; 2695 // return Integer Indefinite 2696 res = 0x8000000000000000ull; 2697 } 2698 BID_RETURN (res); 2699 } 2700 } 2701 // check for non-canonical values (after the check for special values) 2702 if ((C1.w[1] > 0x0001ed09bead87c0ull) 2703 || (C1.w[1] == 0x0001ed09bead87c0ull 2704 && (C1.w[0] > 0x378d8e63ffffffffull)) 2705 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 2706 res = 0x0000000000000000ull; 2707 BID_RETURN (res); 2708 } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) { 2709 // x is 0 2710 res = 0x0000000000000000ull; 2711 BID_RETURN (res); 2712 } else { // x is not special and is not zero 2713 2714 // q = nr. of decimal digits in x 2715 // determine first the nr. of bits in x 2716 if (C1.w[1] == 0) { 2717 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 2718 // split the 64-bit value in two 32-bit halves to avoid rounding errors 2719 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 2720 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion 2721 x_nr_bits = 2722 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2723 } else { // x < 2^32 2724 tmp1.d = (double) (C1.w[0]); // exact conversion 2725 x_nr_bits = 2726 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2727 } 2728 } else { // if x < 2^53 2729 tmp1.d = (double) C1.w[0]; // exact conversion 2730 x_nr_bits = 2731 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2732 } 2733 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1]) 2734 tmp1.d = (double) C1.w[1]; // exact conversion 2735 x_nr_bits = 2736 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 2737 } 2738 q = nr_digits[x_nr_bits - 1].digits; 2739 if (q == 0) { 2740 q = nr_digits[x_nr_bits - 1].digits1; 2741 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi 2742 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi 2743 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) 2744 q++; 2745 } 2746 exp = (x_exp >> 49) - 6176; 2747 if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64) 2748 // set invalid flag 2749 *pfpsf |= INVALID_EXCEPTION; 2750 // return Integer Indefinite 2751 res = 0x8000000000000000ull; 2752 BID_RETURN (res); 2753 } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1) 2754 // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43... 2755 // so x rounded to an integer may or may not fit in a signed 64-bit int 2756 // the cases that do not fit are identified here; the ones that fit 2757 // fall through and will be handled with other cases further, 2758 // under '1 <= q + exp <= 19' 2759 if (x_sign) { // if n < 0 and q + exp = 19 2760 // if n <= -2^63 - 1/2 then n is too large 2761 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2 2762 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=34 2763 // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=34 2764 C.w[1] = 0x0000000000000005ull; 2765 C.w[0] = 0000000000000005ull; 2766 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2767 // 10^(20-q) is 64-bit, and so is C1 2768 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2769 } else if (q == 20) { 2770 ; // C1 * 10^0 = C1 2771 } else { // if 21 <= q <= 34 2772 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2773 } 2774 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2775 // set invalid flag 2776 *pfpsf |= INVALID_EXCEPTION; 2777 // return Integer Indefinite 2778 res = 0x8000000000000000ull; 2779 BID_RETURN (res); 2780 } 2781 // else cases that can be rounded to a 64-bit int fall through 2782 // to '1 <= q + exp <= 19' 2783 } else { // if n > 0 and q + exp = 19 2784 // if n >= 2^63 - 1/2 then n is too large 2785 // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2 2786 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=34 2787 // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=34 2788 C.w[1] = 0x0000000000000004ull; 2789 C.w[0] = 0xfffffffffffffffbull; 2790 if (q <= 19) { // 1 <= q <= 19 => 1 <= 20-q <= 19 => 2791 // 10^(20-q) is 64-bit, and so is C1 2792 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[20 - q]); 2793 } else if (q == 20) { 2794 ; // C1 * 10^0 = C1 2795 } else { // if 21 <= q <= 34 2796 __mul_128x64_to_128 (C, ten2k64[q - 20], C); // max 47-bit x 67-bit 2797 } 2798 if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) { 2799 // set invalid flag 2800 *pfpsf |= INVALID_EXCEPTION; 2801 // return Integer Indefinite 2802 res = 0x8000000000000000ull; 2803 BID_RETURN (res); 2804 } 2805 // else cases that can be rounded to a 64-bit int fall through 2806 // to '1 <= q + exp <= 19' 2807 } 2808 } 2809 // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2 2810 // Note: some of the cases tested for above fall through to this point 2811 // Restore C1 which may have been modified above 2812 C1.w[1] = x.w[1] & MASK_COEFF; 2813 C1.w[0] = x.w[0]; 2814 if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1) 2815 // set inexact flag 2816 *pfpsf |= INEXACT_EXCEPTION; 2817 // return 0 2818 res = 0x0000000000000000ull; 2819 BID_RETURN (res); 2820 } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1) 2821 // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1) 2822 // res = 0 2823 // else 2824 // res = +/-1 2825 ind = q - 1; 2826 if (ind <= 18) { // 0 <= ind <= 18 2827 if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) { 2828 res = 0x0000000000000000ull; // return 0 2829 } else if (x_sign) { // n < 0 2830 res = 0xffffffffffffffffull; // return -1 2831 } else { // n > 0 2832 res = 0x0000000000000001ull; // return +1 2833 } 2834 } else { // 19 <= ind <= 33 2835 if ((C1.w[1] < midpoint128[ind - 19].w[1]) 2836 || ((C1.w[1] == midpoint128[ind - 19].w[1]) 2837 && (C1.w[0] < midpoint128[ind - 19].w[0]))) { 2838 res = 0x0000000000000000ull; // return 0 2839 } else if (x_sign) { // n < 0 2840 res = 0xffffffffffffffffull; // return -1 2841 } else { // n > 0 2842 res = 0x0000000000000001ull; // return +1 2843 } 2844 } 2845 // set inexact flag 2846 *pfpsf |= INEXACT_EXCEPTION; 2847 } else { // if (1 <= q + exp <= 19, 1 <= q <= 34, -33 <= exp <= 18) 2848 // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded 2849 // to nearest to a 64-bit signed integer 2850 if (exp < 0) { // 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 19 2851 ind = -exp; // 1 <= ind <= 33; ind is a synonym for 'x' 2852 // chop off ind digits from the lower part of C1 2853 // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits 2854 tmp64 = C1.w[0]; 2855 if (ind <= 19) { 2856 C1.w[0] = C1.w[0] + midpoint64[ind - 1]; 2857 } else { 2858 C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0]; 2859 C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1]; 2860 } 2861 if (C1.w[0] < tmp64) 2862 C1.w[1]++; 2863 // calculate C* and f* 2864 // C* is actually floor(C*) in this case 2865 // C* and f* need shifting and masking, as shown by 2866 // shiftright128[] and maskhigh128[] 2867 // 1 <= x <= 33 2868 // kx = 10^(-x) = ten2mk128[ind - 1] 2869 // C* = (C1 + 1/2 * 10^x) * 10^(-x) 2870 // the approximation of 10^(-x) was rounded up to 118 bits 2871 __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]); 2872 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2873 Cstar.w[1] = P256.w[3]; 2874 Cstar.w[0] = P256.w[2]; 2875 fstar.w[3] = 0; 2876 fstar.w[2] = P256.w[2] & maskhigh128[ind - 1]; 2877 fstar.w[1] = P256.w[1]; 2878 fstar.w[0] = P256.w[0]; 2879 } else { // 22 <= ind - 1 <= 33 2880 Cstar.w[1] = 0; 2881 Cstar.w[0] = P256.w[3]; 2882 fstar.w[3] = P256.w[3] & maskhigh128[ind - 1]; 2883 fstar.w[2] = P256.w[2]; 2884 fstar.w[1] = P256.w[1]; 2885 fstar.w[0] = P256.w[0]; 2886 } 2887 // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g. 2888 // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999 2889 // if (0 < f* < 10^(-x)) then the result is a midpoint 2890 // if floor(C*) is even then C* = floor(C*) - logical right 2891 // shift; C* has p decimal digits, correct by Prop. 1) 2892 // else if floor(C*) is odd C* = floor(C*)-1 (logical right 2893 // shift; C* has p decimal digits, correct by Pr. 1) 2894 // else 2895 // C* = floor(C*) (logical right shift; C has p decimal digits, 2896 // correct by Property 1) 2897 // n = C* * 10^(e+x) 2898 2899 // shift right C* by Ex-128 = shiftright128[ind] 2900 shift = shiftright128[ind - 1]; // 0 <= shift <= 102 2901 if (ind - 1 <= 21) { // 0 <= ind - 1 <= 21 2902 Cstar.w[0] = 2903 (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift)); 2904 // redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift); 2905 } else { // 22 <= ind - 1 <= 33 2906 Cstar.w[0] = (Cstar.w[0] >> (shift - 64)); // 2 <= shift - 64 <= 38 2907 } 2908 // determine inexactness of the rounding of C* 2909 // if (0 < f* - 1/2 < 10^(-x)) then 2910 // the result is exact 2911 // else // if (f* - 1/2 > T*) then 2912 // the result is inexact 2913 if (ind - 1 <= 2) { 2914 if (fstar.w[1] > 0x8000000000000000ull || 2915 (fstar.w[1] == 0x8000000000000000ull 2916 && fstar.w[0] > 0x0ull)) { 2917 // f* > 1/2 and the result may be exact 2918 tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2 2919 if (tmp64 > ten2mk128trunc[ind - 1].w[1] 2920 || (tmp64 == ten2mk128trunc[ind - 1].w[1] 2921 && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) { 2922 // set the inexact flag 2923 *pfpsf |= INEXACT_EXCEPTION; 2924 } // else the result is exact 2925 } else { // the result is inexact; f2* <= 1/2 2926 // set the inexact flag 2927 *pfpsf |= INEXACT_EXCEPTION; 2928 } 2929 } else if (ind - 1 <= 21) { // if 3 <= ind <= 21 2930 if (fstar.w[3] > 0x0 || 2931 (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) || 2932 (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] && 2933 (fstar.w[1] || fstar.w[0]))) { 2934 // f2* > 1/2 and the result may be exact 2935 // Calculate f2* - 1/2 2936 tmp64 = fstar.w[2] - onehalf128[ind - 1]; 2937 tmp64A = fstar.w[3]; 2938 if (tmp64 > fstar.w[2]) 2939 tmp64A--; 2940 if (tmp64A || tmp64 2941 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 2942 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 2943 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 2944 // set the inexact flag 2945 *pfpsf |= INEXACT_EXCEPTION; 2946 } // else the result is exact 2947 } else { // the result is inexact; f2* <= 1/2 2948 // set the inexact flag 2949 *pfpsf |= INEXACT_EXCEPTION; 2950 } 2951 } else { // if 22 <= ind <= 33 2952 if (fstar.w[3] > onehalf128[ind - 1] || 2953 (fstar.w[3] == onehalf128[ind - 1] && 2954 (fstar.w[2] || fstar.w[1] || fstar.w[0]))) { 2955 // f2* > 1/2 and the result may be exact 2956 // Calculate f2* - 1/2 2957 tmp64 = fstar.w[3] - onehalf128[ind - 1]; 2958 if (tmp64 || fstar.w[2] 2959 || fstar.w[1] > ten2mk128trunc[ind - 1].w[1] 2960 || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] 2961 && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) { 2962 // set the inexact flag 2963 *pfpsf |= INEXACT_EXCEPTION; 2964 } // else the result is exact 2965 } else { // the result is inexact; f2* <= 1/2 2966 // set the inexact flag 2967 *pfpsf |= INEXACT_EXCEPTION; 2968 } 2969 } 2970 2971 // if the result was a midpoint it was rounded away from zero 2972 if (x_sign) 2973 res = -Cstar.w[0]; 2974 else 2975 res = Cstar.w[0]; 2976 } else if (exp == 0) { 2977 // 1 <= q <= 19 2978 // res = +/-C (exact) 2979 if (x_sign) 2980 res = -C1.w[0]; 2981 else 2982 res = C1.w[0]; 2983 } else { // if (exp>0) => 1 <= exp <= 18, 1 <= q < 18, 2 <= q + exp <= 19 2984 // res = +/-C * 10^exp (exact) where this fits in 64-bit integer 2985 if (x_sign) 2986 res = -C1.w[0] * ten2k64[exp]; 2987 else 2988 res = C1.w[0] * ten2k64[exp]; 2989 } 2990 } 2991 } 2992 2993 BID_RETURN (res); 2994 } 2995