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
__quorem10000(unsigned int x,unsigned short * pr)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
__big_binary_to_big_decimal(_big_float * pb,int nsig,_big_float ** ppd,int * sticky)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
__big_decimal_to_string(_big_float * pf,int sticky,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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
__bigfloat_to_decimal(_big_float * bf,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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
__shorten(_big_float * p)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
__double_to_bigfloat(double * px,_big_float * pf)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
__extended_to_bigfloat(extended * px,_big_float * pf)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
__quadruple_to_bigfloat(quadruple * px,_big_float * pf)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
single_to_decimal(single * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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
double_to_decimal(double * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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
extended_to_decimal(extended * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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
quadruple_to_decimal(quadruple * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)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