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 */
59static 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 */
82static 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 */
174static 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 */
337static 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 */
428static 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 */
449static 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 */
475static 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 */
499static 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
528void
529single_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
600void
601double_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
645void
646extended_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
701void
702quadruple_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