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 /*
29 * gcvt - Floating output conversion to minimal length string
30 */
31
32 #include "base_conversion.h"
33 #ifndef PRE41
34 #include <locale.h>
35 #endif
36
37 void
_gcvt(ndigit,pd,trailing,buf)38 _gcvt(ndigit, pd, trailing, buf)
39 int ndigit;
40 decimal_record *pd;
41 char *buf;
42 {
43 char *p, *pstring;
44 int i;
45 static char *inf8 = "Infinity";
46 static char *inf3 = "Inf";
47 static char *nan = "NaN";
48 #ifdef PRE41
49 char decpt = '.';
50 #else
51 char decpt = *(localeconv()->decimal_point);
52 #endif
53
54 p = buf;
55 if (pd->sign)
56 *(p++) = '-';
57 switch (pd->fpclass) {
58 case fp_zero:
59 *(p++) = '0';
60 if (trailing != 0) {
61 *(p++) = decpt;
62 for (i = 0; i < ndigit - 1; i++)
63 *(p++) = '0';
64 }
65 break;
66 case fp_infinity:
67 if (ndigit < 8)
68 pstring = inf3;
69 else
70 pstring = inf8;
71 goto copystring;
72 case fp_quiet:
73 case fp_signaling:
74 pstring = nan;
75 copystring:
76 for (i = 0; *pstring != 0;)
77 *(p++) = *(pstring++);
78 break;
79 default:
80 if ((pd->exponent > 0) || (pd->exponent < -(ndigit + 3))) { /* E format. */
81 char estring[4];
82 int n;
83
84 i = 0;
85 *(p++) = pd->ds[0];
86 *(p++) = decpt;
87 for (i = 1; pd->ds[i] != 0;)
88 *(p++) = pd->ds[i++];
89 if (trailing == 0) { /* Remove trailing zeros and . */
90 p--;
91 while (*p == '0')
92 p--;
93 if (*p != decpt)
94 p++;
95 }
96 *(p++) = 'e';
97 n = pd->exponent + i - 1;
98 if (n >= 0)
99 *(p++) = '+';
100 else {
101 *(p++) = '-';
102 n = -n;
103 }
104 _fourdigitsquick((short unsigned) n, estring);
105 for (i = 0; estring[i] == '0'; i++); /* Find end of zeros. */
106 if (i > 2)
107 i = 2; /* Guarantee two zeros. */
108 for (; i <= 3;)
109 *(p++) = estring[i++]; /* Copy exp digits. */
110 } else { /* F format. */
111 if (pd->exponent >= (1 - ndigit)) { /* x.xxx */
112 for (i = 0; i < (ndigit + pd->exponent);)
113 *(p++) = pd->ds[i++];
114 *(p++) = decpt;
115 if (pd->ds[i] != 0) { /* More follows point. */
116 for (; i < ndigit;)
117 *(p++) = pd->ds[i++];
118 }
119 } else {/* 0.00xxxx */
120 *(p++) = '0';
121 *(p++) = decpt;
122 for (i = 0; i < -(pd->exponent + ndigit); i++)
123 *(p++) = '0';
124 for (i = 0; pd->ds[i] != 0;)
125 *(p++) = pd->ds[i++];
126 }
127 if (trailing == 0) { /* Remove trailing zeros and point. */
128 p--;
129 while (*p == '0')
130 p--;
131 if (*p != decpt)
132 p++;
133 }
134 }
135 }
136 *(p++) = 0;
137 }
138
139 char *
gconvert(number,ndigit,trailing,buf)140 gconvert(number, ndigit, trailing, buf)
141 double number;
142 int ndigit, trailing;
143 char *buf;
144 {
145 decimal_mode dm;
146 decimal_record dr;
147 fp_exception_field_type fef;
148
149 dm.rd = fp_direction;
150 dm.df = floating_form;
151 dm.ndigits = ndigit;
152 double_to_decimal(&number, &dm, &dr, &fef);
153 _gcvt(ndigit, &dr, trailing, buf);
154 return (buf);
155 }
156
157 char *
gcvt(number,ndigit,buf)158 gcvt(number, ndigit, buf)
159 double number;
160 int ndigit;
161 char *buf;
162 {
163 return (gconvert(number, ndigit, 0, buf));
164 }
165