xref: /titanic_41/usr/src/lib/libbc/libc/gen/common/seconvert.c (revision 1816cb7076d3ec8a78ef9ac9f895574e13c43645)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 #pragma ident	"%Z%%M%	%I%	%E% SMI"
23 
24 /*
25  * Copyright (c) 1988 by Sun Microsystems, Inc.
26  */
27 
28 #include "base_conversion.h"
29 
30 char           *
31 seconvert(arg, ndigits, decpt, sign, buf)
32 	single         *arg;
33 	int             ndigits, *decpt, *sign;
34 	char           *buf;
35 {
36 	decimal_mode    dm;
37 	decimal_record  dr;
38 	fp_exception_field_type ef;
39 	int             i;
40 	static char     *nanstring = "NaN";
41 	static char     *infstring = "Infinity";
42 	char           *pc;
43 	int             nc;
44 
45 	dm.rd = fp_direction;	/* Rounding direction. */
46 	dm.df = floating_form;	/* E format. */
47 	dm.ndigits = ndigits;	/* Number of significant digits. */
48 	single_to_decimal(arg, &dm, &dr, &ef);
49 	*sign = dr.sign;
50 	switch (dr.fpclass) {
51 	case fp_normal:
52 	case fp_subnormal:
53 		*decpt = dr.exponent + ndigits;
54 		for (i = 0; i < ndigits; i++)
55 			buf[i] = dr.ds[i];
56 		buf[ndigits] = 0;
57 		break;
58 	case fp_zero:
59 		*decpt = 1;
60 		for (i = 0; i < ndigits; i++)
61 			buf[i] = '0';
62 		buf[ndigits] = 0;
63 		break;
64 	case fp_infinity:
65 		*decpt = 0;
66 		pc = infstring;
67 		if (ndigits < 8)
68 			nc = 3;
69 		else
70 			nc = 8;
71 		goto movestring;
72 	case fp_quiet:
73 	case fp_signaling:
74 		*decpt = 0;
75 		pc = nanstring;
76 		nc = 3;
77 movestring:
78 		for (i = 0; i < nc; i++)
79 			buf[i] = pc[i];
80 		buf[nc] = 0;
81 		break;
82 	}
83 	return buf;		/* For compatibility with ecvt. */
84 }
85 
86 char           *
87 sfconvert(arg, ndigits, decpt, sign, buf)
88 	single         *arg;
89 	int             ndigits, *decpt, *sign;
90 	char           *buf;
91 {
92 	decimal_mode    dm;
93 	decimal_record  dr;
94 	fp_exception_field_type ef;
95 	int             i;
96 
97 	dm.rd = fp_direction;	/* Rounding direction. */
98 	dm.df = fixed_form;	/* F format. */
99 	dm.ndigits = ndigits;	/* Number of digits after point. */
100 	single_to_decimal(arg, &dm, &dr, &ef);
101 	*sign = dr.sign;
102 	switch (dr.fpclass) {
103 	case fp_normal:
104 	case fp_subnormal:
105 		if (ndigits >= 0)
106 			*decpt = dr.ndigits - ndigits;
107 		else
108 			*decpt = dr.ndigits;
109 		for (i = 0; i < dr.ndigits; i++)
110 			buf[i] = dr.ds[i];
111 		buf[dr.ndigits] = 0;
112 		break;
113 	case fp_zero:
114 		*decpt = 0;
115 		buf[0] = '0';
116 		for (i = 1; i < ndigits; i++)
117 			buf[i] = '0';
118 		buf[i] = 0;
119 		break;
120 	case fp_infinity:
121 		*decpt = 0;
122 		if (ndigits < 8)
123 			buf = "Inf";
124 		else
125 			buf = "Infinity";
126 		break;
127 	case fp_quiet:
128 	case fp_signaling:
129 		*decpt = 0;
130 		buf = "NaN";
131 		break;
132 	}
133 	return buf;		/* For compatibility with fcvt. */
134 }
135 
136 extern void    _gcvt();
137 
138 char           *
139 sgconvert(number, ndigit, trailing, buf)
140 	single         *number;
141 	int             ndigit, trailing;
142 	char           *buf;
143 {
144 	decimal_mode    dm;
145 	decimal_record  dr;
146 	fp_exception_field_type fef;
147 
148 	dm.rd = fp_direction;
149 	dm.df = floating_form;
150 	dm.ndigits = ndigit;
151 	single_to_decimal(number, &dm, &dr, &fef);
152 	_gcvt(ndigit, &dr, trailing, buf);
153 	return (buf);
154 }
155