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