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