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 <stdio.h>
104 #include <stdlib.h>
105 #include "local.h"
106 
107 char *	ecvtbuf (double, int, int*, int*, char *);
108 char *	fcvtbuf (double, int, int*, int*, char *);
109 
110 char *
fcvt(double d,int ndigit,int * decpt,int * sign)111 fcvt (double d,
112 	int ndigit,
113 	int *decpt,
114 	int *sign)
115 {
116   return fcvtbuf (d, ndigit, decpt, sign, NULL);
117 }
118 
119 char *
fcvtf(float d,int ndigit,int * decpt,int * sign)120 fcvtf (float d,
121 	int ndigit,
122 	int *decpt,
123 	int *sign)
124 {
125   return fcvt ((double) d, ndigit, decpt, sign);
126 }
127 
128 
129 char *
gcvt(double d,int ndigit,char * buf)130 gcvt (double d,
131 	int ndigit,
132 	char *buf)
133 {
134   char *tbuf = buf;
135   if (d < 0) {
136     *buf = '-';
137     buf++;
138     ndigit--;
139   }
140   return (_gcvt (d, ndigit, buf, 'g', 0) ? tbuf : 0);
141 }
142 
143 
144 char *
gcvtf(float d,int ndigit,char * buf)145 gcvtf (float d,
146 	int ndigit,
147 	char *buf)
148 {
149   double asd = (double) d;
150   return gcvt (asd, ndigit, buf);
151 }
152 
153 
154 char *
ecvt(double d,int ndigit,int * decpt,int * sign)155 ecvt (double d,
156 	int ndigit,
157 	int *decpt,
158 	int *sign)
159 {
160   return ecvtbuf (d, ndigit, decpt, sign, NULL);
161 }
162 
163 char *
ecvtf(float d,int ndigit,int * decpt,int * sign)164 ecvtf (float d,
165 	int ndigit,
166 	int *decpt,
167 	int *sign)
168 {
169   return ecvt ((double) d, ndigit, decpt, sign);
170 }
171