1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Conversion from binary to decimal floating point 29 */ 30 31 #include "lint.h" 32 #include <stdlib.h> 33 #include "base_conversion.h" 34 35 /* 36 * Any sensible programmer would inline the following routine where 37 * it is used below. Unfortunately, the Sun SPARC compilers are not 38 * consistent in generating efficient code for this, so inlining it 39 * as written can cause the *_to_decimal functions to take twice as 40 * long in some cases. 41 * 42 * We might be tempted, then, to rewrite the source to match the most 43 * efficient code the compilers generate and inline that. Alas, the 44 * most efficient code on SPARC uses 32x32->64 bit multiply, which 45 * can't be expressed directly in source code. We could use long long, 46 * which would imply 64x64->64 bit multiply; this would work perfectly 47 * well on SPARC in v8plus mode. But as of Solaris 10, libc for SPARC 48 * is still built in v8 mode, and of course, x86 is another story. 49 * 50 * We could also choose to use an inline template to get the most 51 * efficient code without incurring the full cost of a function call. 52 * Since I expect that would not buy much performance gain, and I 53 * prefer to avoid using inline templates for things that can be 54 * written in a perfectly straightforward way in C, I've settled 55 * for this implementation. I hope that someday the compilers will 56 * get less flaky and/or someone will come up with a better way to 57 * do this. 58 */ 59 static unsigned int 60 __quorem10000(unsigned int x, unsigned short *pr) 61 { 62 *pr = x % 10000; 63 return (x / 10000); 64 } 65 66 /* 67 * Convert the integer part of a nonzero base-2^16 _big_float *pb 68 * to base 10^4 in **ppd. The converted value is accurate to nsig 69 * significant digits. On exit, *sticky is nonzero if *pb had a 70 * nonzero fractional part. If pb->exponent > 0 and **ppd is not 71 * large enough to hold the final converted value (i.e., the con- 72 * verted significand scaled by 2^pb->exponent), then on exit, 73 * *ppd will point to a newly allocated _big_float, which must be 74 * freed by the caller. (The number of significant digits we need 75 * should fit in pd, but __big_float_times_power may allocate new 76 * storage anyway because we could be multiplying by as much as 77 * 2^16271, which would require more than 4000 digits.) 78 * 79 * This routine does not check that **ppd is large enough to hold 80 * the result of converting the significand of *pb. 81 */ 82 static void 83 __big_binary_to_big_decimal(_big_float *pb, int nsig, _big_float **ppd, 84 int *sticky) 85 { 86 _big_float *pd; 87 int i, j, len, s; 88 unsigned int carry; 89 90 pd = *ppd; 91 92 /* convert pb a digit at a time, most significant first */ 93 if (pb->bexponent + ((pb->blength - 1) << 4) >= 0) { 94 carry = pb->bsignificand[pb->blength - 1]; 95 pd->bsignificand[1] = __quorem10000(carry, 96 &pd->bsignificand[0]); 97 len = (pd->bsignificand[1])? 2 : 1; 98 for (i = pb->blength - 2; i >= 0 && 99 pb->bexponent + (i << 4) >= 0; i--) { 100 /* multiply pd by 2^16 and add next digit */ 101 carry = pb->bsignificand[i]; 102 for (j = 0; j < len; j++) { 103 carry += (unsigned int)pd->bsignificand[j] 104 << 16; 105 carry = __quorem10000(carry, 106 &pd->bsignificand[j]); 107 } 108 while (carry != 0) { 109 carry = __quorem10000(carry, 110 &pd->bsignificand[j]); 111 j++; 112 } 113 len = j; 114 } 115 } else { 116 i = pb->blength - 1; 117 len = 0; 118 } 119 120 /* convert any partial digit */ 121 if (i >= 0 && pb->bexponent + (i << 4) > -16) { 122 s = pb->bexponent + (i << 4) + 16; 123 /* multiply pd by 2^s and add partial digit */ 124 carry = pb->bsignificand[i] >> (16 - s); 125 for (j = 0; j < len; j++) { 126 carry += (unsigned int)pd->bsignificand[j] << s; 127 carry = __quorem10000(carry, &pd->bsignificand[j]); 128 } 129 while (carry != 0) { 130 carry = __quorem10000(carry, &pd->bsignificand[j]); 131 j++; 132 } 133 len = j; 134 s = pb->bsignificand[i] & ((1 << (16 - s)) - 1); 135 i--; 136 } else { 137 s = 0; 138 } 139 140 pd->blength = len; 141 pd->bexponent = 0; 142 143 /* continue accumulating sticky flag */ 144 while (i >= 0) 145 s |= pb->bsignificand[i--]; 146 *sticky = s; 147 148 if (pb->bexponent > 0) { 149 /* scale pd by 2^pb->bexponent */ 150 __big_float_times_power(pd, 2, pb->bexponent, nsig, ppd); 151 } 152 } 153 154 /* 155 * Convert a base-10^4 _big_float *pf to a decimal string in *pd, 156 * rounding according to the modes in *pm and recording any exceptions 157 * in *ps. If sticky is nonzero, then additional nonzero digits are 158 * assumed to follow those in *pf. pd->sign must have already been 159 * filled in, and pd->fpclass is not modified. The resulting string 160 * is stored in pd->ds, terminated by a null byte. The length of this 161 * string is stored in pd->ndigits, and the corresponding exponent 162 * is stored in pd->exponent. If the converted value is not exact, 163 * the inexact flag is set in *ps. 164 * 165 * When pm->df == fixed_form, we may discover that the result would 166 * have more than DECIMAL_STRING_LENGTH - 1 digits. In this case, 167 * we put DECIMAL_STRING_LENGTH - 1 digits into *pd, adjusting both 168 * the exponent and the decimal place at which the value is rounded 169 * as need be, and we set the overflow flag in *ps. (Raising overflow 170 * is a bug, but we have to do it to maintain backward compatibility.) 171 * 172 * *pf may be modified. 173 */ 174 static void 175 __big_decimal_to_string(_big_float *pf, int sticky, decimal_mode *pm, 176 decimal_record *pd, fp_exception_field_type *ps) 177 { 178 unsigned short d; 179 int e, er, efirst, elast, i, is, j; 180 char s[4], round; 181 182 /* set e = floor(log10(*pf)) */ 183 i = pf->blength - 1; 184 if (i < 0) { 185 e = pf->bexponent = -DECIMAL_STRING_LENGTH - 2; 186 } else { 187 e = pf->bexponent + (i << 2); 188 d = pf->bsignificand[i]; 189 if (d >= 1000) 190 e += 3; 191 else if (d >= 100) 192 e += 2; 193 else if (d >= 10) 194 e++; 195 } 196 197 /* 198 * Determine the power of ten after which to round and the 199 * powers corresponding to the first and last digits desired 200 * in the result. 201 */ 202 if (pm->df == fixed_form) { 203 /* F format */ 204 er = -pm->ndigits; 205 if (er < 0) { 206 efirst = (e >= 0)? e : -1; 207 elast = er; 208 } else { 209 efirst = (e >= er)? e : ((er > 0)? er - 1 : 0); 210 elast = 0; 211 } 212 213 /* check for possible overflow of pd->ds */ 214 if (efirst - elast >= DECIMAL_STRING_LENGTH - 1) { 215 efirst = e; 216 elast = e - DECIMAL_STRING_LENGTH + 2; 217 if (er < elast) 218 er = elast; 219 *ps |= 1 << fp_overflow; 220 } 221 } else { 222 /* E format */ 223 efirst = e; 224 elast = er = e - pm->ndigits + 1; 225 } 226 227 /* retrieve digits down to the (er - 1) place */ 228 is = 0; 229 for (e = efirst; e >= pf->bexponent + (pf->blength << 2) && 230 e >= er - 1; e--) 231 pd->ds[is++] = '0'; 232 233 i = pf->blength - 1; 234 j = 3 - ((e - pf->bexponent) & 3); 235 if (j > 0 && e >= er - 1) { 236 __four_digits_quick(pf->bsignificand[i], s); 237 while (j <= 3 && e >= er - 1) { 238 pd->ds[is++] = s[j++]; 239 e--; 240 } 241 while (j <= 3) 242 sticky |= (s[j++] - '0'); 243 i--; 244 } 245 246 while ((i | (e - er - 2)) >= 0) { /* i >= 0 && e >= er + 2 */ 247 __four_digits_quick(pf->bsignificand[i], pd->ds + is); 248 is += 4; 249 e -= 4; 250 i--; 251 } 252 253 if (i >= 0) { 254 if (e >= er - 1) { 255 __four_digits_quick(pf->bsignificand[i], s); 256 for (j = 0; e >= er - 1; j++) { 257 pd->ds[is++] = s[j]; 258 e--; 259 } 260 while (j <= 3) 261 sticky |= (s[j++] - '0'); 262 i--; 263 } 264 } else { 265 while (e-- >= er - 1) 266 pd->ds[is++] = '0'; 267 } 268 269 /* collect rounding information */ 270 round = pd->ds[--is]; 271 while (i >= 0) 272 sticky |= pf->bsignificand[i--]; 273 274 /* add more trailing zeroes if need be */ 275 for (e = er - 1; e >= elast; e--) 276 pd->ds[is++] = '0'; 277 278 pd->exponent = elast; 279 pd->ndigits = is; 280 pd->ds[is] = '\0'; 281 282 /* round */ 283 if (round == '0' && sticky == 0) 284 return; 285 286 *ps |= 1 << fp_inexact; 287 288 switch (pm->rd) { 289 case fp_nearest: 290 if (round < '5' || (round == '5' && sticky == 0 && 291 (is <= 0 || (pd->ds[is - 1] & 1) == 0))) 292 return; 293 break; 294 295 case fp_positive: 296 if (pd->sign) 297 return; 298 break; 299 300 case fp_negative: 301 if (!pd->sign) 302 return; 303 break; 304 305 default: 306 return; 307 } 308 309 /* round up */ 310 for (i = efirst - er; i >= 0 && pd->ds[i] == '9'; i--) 311 pd->ds[i] = '0'; 312 if (i >= 0) { 313 (pd->ds[i])++; 314 } else { 315 /* rounding carry out has occurred */ 316 pd->ds[0] = '1'; 317 if (pm->df == floating_form) { 318 pd->exponent++; 319 } else if (is == DECIMAL_STRING_LENGTH - 1) { 320 pd->exponent++; 321 *ps |= 1 << fp_overflow; 322 } else { 323 if (is > 0) 324 pd->ds[is] = '0'; 325 is++; 326 pd->ndigits = is; 327 pd->ds[is] = '\0'; 328 } 329 } 330 } 331 332 /* 333 * Convert a binary floating point value represented by *pf to a 334 * decimal record *pd according to the modes in *pm. Any exceptions 335 * incurred are passed back via *ps. 336 */ 337 static void 338 __bigfloat_to_decimal(_big_float *bf, decimal_mode *pm, decimal_record *pd, 339 fp_exception_field_type *ps) 340 { 341 _big_float *pbf, *pbd, d; 342 int sticky, powten, sigbits, sigdigits, i; 343 344 /* 345 * If pm->ndigits is too large or too small, set the overflow 346 * flag in *ps and do nothing. (Raising overflow is a bug, 347 * but we have to do it to maintain backward compatibility.) 348 */ 349 if (pm->ndigits >= DECIMAL_STRING_LENGTH || pm->ndigits <= 350 ((pm->df == floating_form)? 0 : -DECIMAL_STRING_LENGTH)) { 351 *ps = 1 << fp_overflow; 352 return; 353 } 354 355 pbf = bf; 356 powten = 0; 357 358 /* pre-scale to get the digits we want into the integer part */ 359 if (pm->df == fixed_form) { 360 /* F format */ 361 if (pm->ndigits >= 0 && bf->bexponent < 0) { 362 /* 363 * Scale by 10^min(-bf->bexponent, pm->ndigits + 1). 364 */ 365 powten = pm->ndigits + 1; 366 if (powten > -bf->bexponent) 367 powten = -bf->bexponent; 368 /* 369 * Take sigbits large enough to get all integral 370 * digits correct. 371 */ 372 sigbits = bf->bexponent + (bf->blength << 4) + 373 (((powten * 217706) + 65535) >> 16); 374 if (sigbits < 1) 375 sigbits = 1; 376 __big_float_times_power(bf, 10, powten, sigbits, &pbf); 377 } 378 sigdigits = DECIMAL_STRING_LENGTH + 1; 379 } else { 380 /* E format */ 381 if (bf->bexponent < 0) { 382 /* i is a lower bound on log2(x) */ 383 i = bf->bexponent + ((bf->blength - 1) << 4); 384 if (i <= 0 || ((i * 19728) >> 16) < pm->ndigits + 1) { 385 /* 386 * Scale by 10^min(-bf->bexponent, 387 * pm->ndigits + 1 + u) where u is 388 * an upper bound on -log10(x). 389 */ 390 powten = pm->ndigits + 1; 391 if (i < 0) 392 powten += ((-i * 19729) + 65535) >> 16; 393 else if (i > 0) 394 powten -= (i * 19728) >> 16; 395 if (powten > -bf->bexponent) 396 powten = -bf->bexponent; 397 /* 398 * Take sigbits large enough to get 399 * all integral digits correct. 400 */ 401 sigbits = i + 16 + 402 (((powten * 217706) + 65535) >> 16); 403 __big_float_times_power(bf, 10, powten, 404 sigbits, &pbf); 405 } 406 } 407 sigdigits = pm->ndigits + 2; 408 } 409 410 /* convert to base 10^4 */ 411 d.bsize = _BIG_FLOAT_SIZE; 412 pbd = &d; 413 __big_binary_to_big_decimal(pbf, sigdigits, &pbd, &sticky); 414 415 /* adjust pbd->bexponent based on the scale factor above */ 416 pbd->bexponent -= powten; 417 418 /* convert to ASCII */ 419 __big_decimal_to_string(pbd, sticky, pm, pd, ps); 420 421 if (pbf != bf) 422 (void) free((void *)pbf); 423 if (pbd != &d) 424 (void) free((void *)pbd); 425 } 426 427 /* remove trailing zeroes from the significand of p */ 428 static void 429 __shorten(_big_float *p) 430 { 431 int length = p->blength; 432 int zeros, i; 433 434 /* count trailing zeros */ 435 for (zeros = 0; zeros < length && p->bsignificand[zeros] == 0; zeros++) 436 ; 437 if (zeros) { 438 length -= zeros; 439 p->bexponent += zeros << 4; 440 for (i = 0; i < length; i++) 441 p->bsignificand[i] = p->bsignificand[i + zeros]; 442 p->blength = length; 443 } 444 } 445 446 /* 447 * Unpack a normal or subnormal double into a _big_float. 448 */ 449 static void 450 __double_to_bigfloat(double *px, _big_float *pf) 451 { 452 double_equivalence *x; 453 454 x = (double_equivalence *)px; 455 pf->bsize = _BIG_FLOAT_SIZE; 456 pf->bexponent = x->f.msw.exponent - DOUBLE_BIAS - 52; 457 pf->blength = 4; 458 pf->bsignificand[0] = x->f.significand2 & 0xffff; 459 pf->bsignificand[1] = x->f.significand2 >> 16; 460 pf->bsignificand[2] = x->f.msw.significand & 0xffff; 461 pf->bsignificand[3] = x->f.msw.significand >> 16; 462 if (x->f.msw.exponent == 0) { 463 pf->bexponent++; 464 while (pf->bsignificand[pf->blength - 1] == 0) 465 pf->blength--; 466 } else { 467 pf->bsignificand[3] += 0x10; 468 } 469 __shorten(pf); 470 } 471 472 /* 473 * Unpack a normal or subnormal extended into a _big_float. 474 */ 475 static void 476 __extended_to_bigfloat(extended *px, _big_float *pf) 477 { 478 extended_equivalence *x; 479 480 x = (extended_equivalence *)px; 481 pf->bsize = _BIG_FLOAT_SIZE; 482 pf->bexponent = x->f.msw.exponent - EXTENDED_BIAS - 63; 483 pf->blength = 4; 484 pf->bsignificand[0] = x->f.significand2 & 0xffff; 485 pf->bsignificand[1] = x->f.significand2 >> 16; 486 pf->bsignificand[2] = x->f.significand & 0xffff; 487 pf->bsignificand[3] = x->f.significand >> 16; 488 if (x->f.msw.exponent == 0) { 489 pf->bexponent++; 490 while (pf->bsignificand[pf->blength - 1] == 0) 491 pf->blength--; 492 } 493 __shorten(pf); 494 } 495 496 /* 497 * Unpack a normal or subnormal quad into a _big_float. 498 */ 499 static void 500 __quadruple_to_bigfloat(quadruple *px, _big_float *pf) 501 { 502 quadruple_equivalence *x; 503 504 x = (quadruple_equivalence *)px; 505 pf->bsize = _BIG_FLOAT_SIZE; 506 pf->bexponent = x->f.msw.exponent - QUAD_BIAS - 112; 507 pf->bsignificand[0] = x->f.significand4 & 0xffff; 508 pf->bsignificand[1] = x->f.significand4 >> 16; 509 pf->bsignificand[2] = x->f.significand3 & 0xffff; 510 pf->bsignificand[3] = x->f.significand3 >> 16; 511 pf->bsignificand[4] = x->f.significand2 & 0xffff; 512 pf->bsignificand[5] = x->f.significand2 >> 16; 513 pf->bsignificand[6] = x->f.msw.significand; 514 if (x->f.msw.exponent == 0) { 515 pf->blength = 7; 516 pf->bexponent++; 517 while (pf->bsignificand[pf->blength - 1] == 0) 518 pf->blength--; 519 } else { 520 pf->blength = 8; 521 pf->bsignificand[7] = 1; 522 } 523 __shorten(pf); 524 } 525 526 /* PUBLIC ROUTINES */ 527 528 void 529 single_to_decimal(single *px, decimal_mode *pm, decimal_record *pd, 530 fp_exception_field_type *ps) 531 { 532 single_equivalence *kluge; 533 _big_float bf; 534 fp_exception_field_type ef; 535 double x; 536 537 kluge = (single_equivalence *)px; 538 pd->sign = kluge->f.msw.sign; 539 540 /* decide what to do based on the class of x */ 541 if (kluge->f.msw.exponent == 0) { /* 0 or subnormal */ 542 if (kluge->f.msw.significand == 0) { 543 pd->fpclass = fp_zero; 544 *ps = 0; 545 return; 546 } else { 547 #if defined(__sparc) || defined(__amd64) 548 int i; 549 550 pd->fpclass = fp_subnormal; 551 /* 552 * On SPARC when nonstandard mode is enabled, 553 * or on x64 when FTZ mode is enabled, simply 554 * converting *px to double can flush a sub- 555 * normal value to zero, so we have to go 556 * through all this nonsense instead. 557 */ 558 i = *(int *)px; 559 x = (double)(i & ~0x80000000); 560 if (i < 0) 561 x = -x; 562 x *= 1.401298464324817070923730e-45; /* 2^-149 */ 563 ef = 0; 564 if (__fast_double_to_decimal(&x, pm, pd, &ef)) { 565 __double_to_bigfloat(&x, &bf); 566 __bigfloat_to_decimal(&bf, pm, pd, &ef); 567 } 568 if (ef != 0) 569 __base_conversion_set_exception(ef); 570 *ps = ef; 571 return; 572 #else 573 pd->fpclass = fp_subnormal; 574 #endif 575 } 576 } else if (kluge->f.msw.exponent == 0xff) { /* inf or nan */ 577 if (kluge->f.msw.significand == 0) 578 pd->fpclass = fp_infinity; 579 else if (kluge->f.msw.significand >= 0x400000) 580 pd->fpclass = fp_quiet; 581 else 582 pd->fpclass = fp_signaling; 583 *ps = 0; 584 return; 585 } else { 586 pd->fpclass = fp_normal; 587 } 588 589 ef = 0; 590 x = *px; 591 if (__fast_double_to_decimal(&x, pm, pd, &ef)) { 592 __double_to_bigfloat(&x, &bf); 593 __bigfloat_to_decimal(&bf, pm, pd, &ef); 594 } 595 if (ef != 0) 596 __base_conversion_set_exception(ef); 597 *ps = ef; 598 } 599 600 void 601 double_to_decimal(double *px, decimal_mode *pm, decimal_record *pd, 602 fp_exception_field_type *ps) 603 { 604 double_equivalence *kluge; 605 _big_float bf; 606 fp_exception_field_type ef; 607 608 kluge = (double_equivalence *)px; 609 pd->sign = kluge->f.msw.sign; 610 611 /* decide what to do based on the class of x */ 612 if (kluge->f.msw.exponent == 0) { /* 0 or subnormal */ 613 if (kluge->f.msw.significand == 0 && 614 kluge->f.significand2 == 0) { 615 pd->fpclass = fp_zero; 616 *ps = 0; 617 return; 618 } else { 619 pd->fpclass = fp_subnormal; 620 } 621 } else if (kluge->f.msw.exponent == 0x7ff) { /* inf or nan */ 622 if (kluge->f.msw.significand == 0 && 623 kluge->f.significand2 == 0) 624 pd->fpclass = fp_infinity; 625 else if (kluge->f.msw.significand >= 0x80000) 626 pd->fpclass = fp_quiet; 627 else 628 pd->fpclass = fp_signaling; 629 *ps = 0; 630 return; 631 } else { 632 pd->fpclass = fp_normal; 633 } 634 635 ef = 0; 636 if (__fast_double_to_decimal(px, pm, pd, &ef)) { 637 __double_to_bigfloat(px, &bf); 638 __bigfloat_to_decimal(&bf, pm, pd, &ef); 639 } 640 if (ef != 0) 641 __base_conversion_set_exception(ef); 642 *ps = ef; 643 } 644 645 void 646 extended_to_decimal(extended *px, decimal_mode *pm, decimal_record *pd, 647 fp_exception_field_type *ps) 648 { 649 extended_equivalence *kluge; 650 _big_float bf; 651 fp_exception_field_type ef; 652 653 kluge = (extended_equivalence *)px; 654 pd->sign = kluge->f.msw.sign; 655 656 /* decide what to do based on the class of x */ 657 if (kluge->f.msw.exponent == 0) { /* 0 or subnormal */ 658 if ((kluge->f.significand | kluge->f.significand2) == 0) { 659 pd->fpclass = fp_zero; 660 *ps = 0; 661 return; 662 } else { 663 /* 664 * x could be a pseudo-denormal, but the distinction 665 * doesn't matter 666 */ 667 pd->fpclass = fp_subnormal; 668 } 669 } else if ((kluge->f.significand & 0x80000000) == 0) { 670 /* 671 * In Intel's extended format, if the exponent is 672 * nonzero but the explicit integer bit is zero, this 673 * is an "unsupported format" bit pattern; treat it 674 * like a signaling NaN. 675 */ 676 pd->fpclass = fp_signaling; 677 *ps = 0; 678 return; 679 } else if (kluge->f.msw.exponent == 0x7fff) { /* inf or nan */ 680 if (((kluge->f.significand & 0x7fffffff) | 681 kluge->f.significand2) == 0) 682 pd->fpclass = fp_infinity; 683 else if ((kluge->f.significand & 0x7fffffff) >= 0x40000000) 684 pd->fpclass = fp_quiet; 685 else 686 pd->fpclass = fp_signaling; 687 *ps = 0; 688 return; 689 } else { 690 pd->fpclass = fp_normal; 691 } 692 693 ef = 0; 694 __extended_to_bigfloat(px, &bf); 695 __bigfloat_to_decimal(&bf, pm, pd, &ef); 696 if (ef != 0) 697 __base_conversion_set_exception(ef); 698 *ps = ef; 699 } 700 701 void 702 quadruple_to_decimal(quadruple *px, decimal_mode *pm, decimal_record *pd, 703 fp_exception_field_type *ps) 704 { 705 quadruple_equivalence *kluge; 706 _big_float bf; 707 fp_exception_field_type ef; 708 709 kluge = (quadruple_equivalence *)px; 710 pd->sign = kluge->f.msw.sign; 711 712 /* decide what to do based on the class of x */ 713 if (kluge->f.msw.exponent == 0) { /* 0 or subnormal */ 714 if (kluge->f.msw.significand == 0 && 715 (kluge->f.significand2 | kluge->f.significand3 | 716 kluge->f.significand4) == 0) { 717 pd->fpclass = fp_zero; 718 *ps = 0; 719 return; 720 } else { 721 pd->fpclass = fp_subnormal; 722 } 723 } else if (kluge->f.msw.exponent == 0x7fff) { /* inf or nan */ 724 if (kluge->f.msw.significand == 0 && 725 (kluge->f.significand2 | kluge->f.significand3 | 726 kluge->f.significand4) == 0) 727 pd->fpclass = fp_infinity; 728 else if (kluge->f.msw.significand >= 0x8000) 729 pd->fpclass = fp_quiet; 730 else 731 pd->fpclass = fp_signaling; 732 *ps = 0; 733 return; 734 } else { 735 pd->fpclass = fp_normal; 736 } 737 738 ef = 0; 739 __quadruple_to_bigfloat(px, &bf); 740 __bigfloat_to_decimal(&bf, pm, pd, &ef); 741 if (ef != 0) 742 __base_conversion_set_exception(ef); 743 *ps = ef; 744 } 745