1 /*
2 FUNCTION
3 <<ecvt>>, <<ecvtf>>, <<fcvt>>, <<fcvtf>>---double or float to string
4 
5 INDEX
6 	ecvt
7 INDEX
8 	ecvtf
9 INDEX
10 	fcvt
11 INDEX
12 	fcvtf
13 
14 SYNOPSIS
15 	#include <stdlib.h>
16 
17 	char *ecvt(double <[val]>, int <[chars]>, int *<[decpt]>, int *<[sgn]>);
18 	char *ecvtf(float <[val]>, int <[chars]>, int *<[decpt]>, int *<[sgn]>);
19 
20 	char *fcvt(double <[val]>, int <[decimals]>,
21                    int *<[decpt]>, int *<[sgn]>);
22 	char *fcvtf(float <[val]>, int <[decimals]>,
23                     int *<[decpt]>, int *<[sgn]>);
24 
25 DESCRIPTION
26 <<ecvt>> and <<fcvt>> produce (null-terminated) strings of digits
27 representating the <<double>> number <[val]>.
28 <<ecvtf>> and <<fcvtf>> produce the corresponding character
29 representations of <<float>> numbers.
30 
31 (The <<stdlib>> functions <<ecvtbuf>> and <<fcvtbuf>> are reentrant
32 versions of <<ecvt>> and <<fcvt>>.)
33 
34 The only difference between <<ecvt>> and <<fcvt>> is the
35 interpretation of the second argument (<[chars]> or <[decimals]>).
36 For <<ecvt>>, the second argument <[chars]> specifies the total number
37 of characters to write (which is also the number of significant digits
38 in the formatted string, since these two functions write only digits).
39 For <<fcvt>>, the second argument <[decimals]> specifies the number of
40 characters to write after the decimal point; all digits for the integer
41 part of <[val]> are always included.
42 
43 Since <<ecvt>> and <<fcvt>> write only digits in the output string,
44 they record the location of the decimal point in <<*<[decpt]>>>, and
45 the sign of the number in <<*<[sgn]>>>.  After formatting a number,
46 <<*<[decpt]>>> contains the number of digits to the left of the
47 decimal point.  <<*<[sgn]>>> contains <<0>> if the number is positive,
48 and <<1>> if it is negative.
49 
50 RETURNS
51 All four functions return a pointer to the new string containing a
52 character representation of <[val]>.
53 
54 PORTABILITY
55 None of these functions are ANSI C.
56 
57 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
58 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
59 
60 NEWPAGE
61 FUNCTION
62 <<gcvt>>, <<gcvtf>>---format double or float as string
63 
64 INDEX
65 	gcvt
66 INDEX
67 	gcvtf
68 
69 SYNOPSIS
70 	#include <stdlib.h>
71 
72 	char *gcvt(double <[val]>, int <[precision]>, char *<[buf]>);
73 	char *gcvtf(float <[val]>, int <[precision]>, char *<[buf]>);
74 
75 DESCRIPTION
76 <<gcvt>> writes a fully formatted number as a null-terminated
77 string in the buffer <<*<[buf]>>>.  <<gcvtf>> produces corresponding
78 character representations of <<float>> numbers.
79 
80 <<gcvt>> uses the same rules as the <<printf>> format
81 `<<%.<[precision]>g>>'---only negative values are signed (with
82 `<<->>'), and either exponential or ordinary decimal-fraction format
83 is chosen depending on the number of significant digits (specified by
84 <[precision]>).
85 
86 RETURNS
87 The result is a pointer to the formatted representation of <[val]>
88 (the same as the argument <[buf]>).
89 
90 PORTABILITY
91 Neither function is ANSI C.
92 
93 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
94 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
95 */
96 
97 #define _XOPEN_SOURCE
98 #define _XOPEN_SOURCE_EXTENDED
99 #include <_ansi.h>
100 #include <stdio.h>
101 #include <stdlib.h>
102 #include "local.h"
103 
104 char *	ecvtbuf (double, int, int*, int*, char *);
105 char *	fcvtbuf (double, int, int*, int*, char *);
106 
107 char *
fcvt(double d,int ndigit,int * decpt,int * sign)108 fcvt (double d,
109 	int ndigit,
110 	int *decpt,
111 	int *sign)
112 {
113   return fcvtbuf (d, ndigit, decpt, sign, NULL);
114 }
115 
116 char *
fcvtf(float d,int ndigit,int * decpt,int * sign)117 fcvtf (float d,
118 	int ndigit,
119 	int *decpt,
120 	int *sign)
121 {
122   return fcvt ((float) d, ndigit, decpt, sign);
123 }
124 
125 
126 char *
gcvt(double d,int ndigit,char * buf)127 gcvt (double d,
128 	int ndigit,
129 	char *buf)
130 {
131   char *tbuf = buf;
132   if (d < 0) {
133     *buf = '-';
134     buf++;
135     ndigit--;
136   }
137   return (_gcvt (d, ndigit, buf, 'g', 0) ? tbuf : 0);
138 }
139 
140 
141 char *
gcvtf(float d,int ndigit,char * buf)142 gcvtf (float d,
143 	int ndigit,
144 	char *buf)
145 {
146   double asd = d;
147   return gcvt (asd, ndigit, buf);
148 }
149 
150 
151 char *
ecvt(double d,int ndigit,int * decpt,int * sign)152 ecvt (double d,
153 	int ndigit,
154 	int *decpt,
155 	int *sign)
156 {
157   return ecvtbuf (d, ndigit, decpt, sign, NULL);
158 }
159 
160 char *
ecvtf(float d,int ndigit,int * decpt,int * sign)161 ecvtf (float d,
162 	int ndigit,
163 	int *decpt,
164 	int *sign)
165 {
166   return ecvt ((double) d, ndigit, decpt, sign);
167 }
168