1: # include <sccs.h>
2:
3: SCCSID(@(#)ftoa.c 8.1 12/31/84)
4:
5: # define MAXDIG 25
6:
7: /*
8: ** FLOATING POINT TO ASCII CONVERSION
9: **
10: ** 'Value' is converted to an ascii character string and stored
11: ** into 'ascii'. Ascii should have room for at least 'width' + 1
12: ** characters. 'Width' is the width of the output field (max).
13: ** 'Prec' is the number of characters to put after the decimal
14: ** point. The format of the output string is controlled by
15: ** 'format'.
16: **
17: ** 'Format' can be:
18: ** e or E: "E" format output
19: ** f or F: "F" format output
20: ** g or G: "F" format output if it will fit, otherwise
21: ** use "E" format.
22: ** n or N: same as G, but decimal points will not always
23: ** be aligned.
24: **
25: ** If 'format' is upper case, the "E" comes out in upper case;
26: ** otherwise it comes out in lower case.
27: **
28: ** When the field width is not big enough, it fills the field with
29: ** stars ("*****") and returns zero. Normal return is the width
30: ** of the output field (sometimes shorter than 'width').
31: */
32:
33: ftoa(value, ascii, width, prec1, format)
34: double value;
35: char *ascii;
36: int width;
37: int prec1;
38: char format;
39: {
40: auto int expon;
41: auto int sign;
42: register int avail;
43: register char *a;
44: register char *p;
45: char mode;
46: int lowercase;
47: int prec;
48: extern char *ecvt(), *fcvt();
49:
50: prec = prec1;
51: mode = format;
52: lowercase = 'a' - 'A';
53: if (mode >= 'a')
54: mode -= 'a' - 'A';
55: else
56: lowercase = 0;
57:
58: if (mode != 'E')
59: {
60: /* try 'F' style output */
61: p = fcvt(value, prec, &expon, &sign);
62: avail = width;
63: a = ascii;
64:
65: /* output sign */
66: if (sign)
67: {
68: avail--;
69: *a++ = '-';
70: }
71:
72: /* output '0' before the decimal point */
73: if (expon <= 0)
74: {
75: *a++ = '0';
76: avail--;
77: }
78:
79: /* compute space length left after dec pt and fraction */
80: avail -= prec + 1;
81: if (mode == 'G')
82: avail -= 4;
83:
84: if (avail >= expon)
85: {
86:
87: /* it fits. output */
88: while (expon > 0)
89: {
90: /* output left of dp */
91: expon--;
92: if (*p)
93: {
94: *a++ = *p++;
95: }
96: else
97: *a++ = '0';
98: }
99:
100: /* output fraction (right of dec pt) */
101: avail = expon;
102: goto frac_out;
103: }
104: /* won't fit; let's hope for G format */
105: }
106:
107: if (mode != 'F')
108: {
109: /* try to do E style output */
110: p = ecvt(value, prec + 1, &expon, &sign);
111: avail = width - 5;
112: a = ascii;
113:
114: /* output the sign */
115: if (sign)
116: {
117: *a++ = '-';
118: avail--;
119: }
120: }
121:
122: /* check for field too small */
123: if (mode == 'F' || avail < prec)
124: {
125: /* sorry joker, you lose */
126: a = ascii;
127: for (avail = width; avail > 0; avail--)
128: *a++ = '*';
129: *a = 0;
130: return (0);
131: }
132:
133: /* it fits; output the number */
134: mode = 'E';
135:
136: /* output the LHS single digit */
137: *a++ = *p++;
138: expon--;
139:
140: /* output the rhs */
141: avail = 1;
142:
143: frac_out:
144: *a++ = '.';
145: while (prec > 0)
146: {
147: prec--;
148: if (avail < 0)
149: {
150: avail++;
151: *a++ = '0';
152: }
153: else
154: {
155: if (*p)
156: *a++ = *p++;
157: else
158: *a++ = '0';
159: }
160: }
161:
162: /* output the exponent */
163: if (mode == 'E')
164: {
165: *a++ = 'E' + lowercase;
166: if (expon < 0)
167: {
168: *a++ = '-';
169: expon = -expon;
170: }
171: else
172: *a++ = '+';
173: *a++ = (expon / 10) % 10 + '0';
174: *a++ = expon % 10 + '0';
175: }
176:
177: /* output spaces on the end in G format */
178: if (mode == 'G')
179: {
180: *a++ = ' ';
181: *a++ = ' ';
182: *a++ = ' ';
183: *a++ = ' ';
184: }
185:
186: /* finally, we can return */
187: *a = 0;
188: avail = a - ascii;
189: return (avail);
190: }
Defined functions
ftoa
defined in line
3;
never used
Defined macros
MAXDIG
defined in line
5;
never used