xref: /titanic_50/usr/src/lib/libbc/libc/gen/common/econvert.c (revision c77a61a72b5ecdc507d6cf104142edd371a16c84)
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 static char     *nanstring = "NaN";
31 static char     *infstring = "Infinity";
32 
33 char           *
34 econvert(arg, ndigits, decpt, sign, buf)
35 	double          arg;
36 	int             ndigits, *decpt, *sign;
37 	char           *buf;
38 {
39 	decimal_mode    dm;
40 	decimal_record  dr;
41 	fp_exception_field_type ef;
42 	int             i;
43 	char           *pc;
44 	int             nc;
45 
46 	dm.rd = fp_direction;	/* Rounding direction. */
47 	dm.df = floating_form;	/* E format. */
48 	dm.ndigits = ndigits;	/* Number of significant digits. */
49 	double_to_decimal(&arg, &dm, &dr, &ef);
50 	*sign = dr.sign;
51 	switch (dr.fpclass) {
52 	case fp_normal:
53 	case fp_subnormal:
54 		*decpt = dr.exponent + ndigits;
55 		for (i = 0; i < ndigits; i++)
56 			buf[i] = dr.ds[i];
57 		buf[ndigits] = 0;
58 		break;
59 	case fp_zero:
60 		*decpt = 1;
61 		for (i = 0; i < ndigits; i++)
62 			buf[i] = '0';
63 		buf[ndigits] = 0;
64 		break;
65 	case fp_infinity:
66 		*decpt = 0;
67 		pc = infstring;
68 		if (ndigits < 8)
69 			nc = 3;
70 		else
71 			nc = 8;
72 		goto movestring;
73 	case fp_quiet:
74 	case fp_signaling:
75 		*decpt = 0;
76 		pc = nanstring;
77 		nc = 3;
78 movestring:
79 		for (i = 0; i < nc; i++)
80 			buf[i] = pc[i];
81 		buf[nc] = 0;
82 		break;
83 	}
84 	return buf;		/* For compatibility with ecvt. */
85 }
86 
87 char           *
88 fconvert(arg, ndigits, decpt, sign, buf)
89 	double          arg;
90 	int             ndigits, *decpt, *sign;
91 	char           *buf;
92 {
93 	decimal_mode    dm;
94 	decimal_record  dr;
95 	fp_exception_field_type ef;
96 	int             i;
97 	char           *pc;
98 	int             nc;
99 
100 	dm.rd = fp_direction;	/* Rounding direction. */
101 	dm.df = fixed_form;	/* F format. */
102 	dm.ndigits = ndigits;	/* Number of digits after point. */
103 	double_to_decimal(&arg, &dm, &dr, &ef);
104 	*sign = dr.sign;
105 	switch (dr.fpclass) {
106 	case fp_normal:
107 	case fp_subnormal:
108 		if (ndigits >= 0)
109 			*decpt = dr.ndigits - ndigits;
110 		else
111 			*decpt = dr.ndigits;
112 		for (i = 0; i < dr.ndigits; i++)
113 			buf[i] = dr.ds[i];
114 		buf[dr.ndigits] = 0;
115 		break;
116 	case fp_zero:
117 		*decpt = 0;
118 		buf[0] = '0';
119 		for (i = 1; i < ndigits; i++)
120 			buf[i] = '0';
121 		buf[i] = 0;
122 		break;
123 	case fp_infinity:
124 		*decpt = 0;
125 		pc = infstring;
126 		if (ndigits < 8)
127 			nc = 3;
128 		else
129 			nc = 8;
130 		goto movestring;
131 	case fp_quiet:
132 	case fp_signaling:
133 		*decpt = 0;
134 		pc = nanstring;
135 		nc = 3;
136 movestring:
137 		for (i = 0; i < nc; i++)
138 			buf[i] = pc[i];
139 		buf[nc] = 0;
140 		break;
141 	}
142 	return buf;		/* For compatibility with fcvt. */
143 }
144