1 | /*
|
---|
2 | * fltpr.c - print floating point numbers
|
---|
3 | */
|
---|
4 | /* $Header: /cvsup/minix/src/lib/gnu/ieee_float/fphook.c,v 1.1 2005/10/10 15:28:15 beng Exp $ */
|
---|
5 |
|
---|
6 | #ifndef NOFLOAT
|
---|
7 | #include <string.h>
|
---|
8 | #include <stdarg.h>
|
---|
9 | #include "../stdio/loc_incl.h"
|
---|
10 | int _fp_hook = 1;
|
---|
11 |
|
---|
12 | static char *
|
---|
13 | _pfloat(long double r, register char *s, int n, int flags)
|
---|
14 | {
|
---|
15 | register char *s1;
|
---|
16 | int sign, dp;
|
---|
17 | register int i;
|
---|
18 |
|
---|
19 | s1 = _fcvt(r, n, &dp, &sign);
|
---|
20 | if (sign)
|
---|
21 | *s++ = '-';
|
---|
22 | else if (flags & FL_SIGN)
|
---|
23 | *s++ = '+';
|
---|
24 | else if (flags & FL_SPACE)
|
---|
25 | *s++ = ' ';
|
---|
26 |
|
---|
27 | if (dp<=0)
|
---|
28 | *s++ = '0';
|
---|
29 | for (i=dp; i>0; i--)
|
---|
30 | if (*s1) *s++ = *s1++;
|
---|
31 | else *s++ = '0';
|
---|
32 | if (((i=n) > 0) || (flags & FL_ALT))
|
---|
33 | *s++ = '.';
|
---|
34 | while (++dp <= 0) {
|
---|
35 | if (--i<0)
|
---|
36 | break;
|
---|
37 | *s++ = '0';
|
---|
38 | }
|
---|
39 | while (--i >= 0)
|
---|
40 | if (*s1) *s++ = *s1++;
|
---|
41 | else *s++ = '0';
|
---|
42 | return s;
|
---|
43 | }
|
---|
44 |
|
---|
45 | static char *
|
---|
46 | _pscien(long double r, register char *s, int n, int flags)
|
---|
47 | {
|
---|
48 | int sign, dp;
|
---|
49 | register char *s1;
|
---|
50 |
|
---|
51 | s1 = _ecvt(r, n + 1, &dp, &sign);
|
---|
52 | if (sign)
|
---|
53 | *s++ = '-';
|
---|
54 | else if (flags & FL_SIGN)
|
---|
55 | *s++ = '+';
|
---|
56 | else if (flags & FL_SPACE)
|
---|
57 | *s++ = ' ';
|
---|
58 |
|
---|
59 | *s++ = *s1++;
|
---|
60 | if ((n > 0) || (flags & FL_ALT))
|
---|
61 | *s++ = '.';
|
---|
62 | while (--n >= 0)
|
---|
63 | if (*s1) *s++ = *s1++;
|
---|
64 | else *s++ = '0';
|
---|
65 | *s++ = 'e';
|
---|
66 | if ( r != 0 ) --dp ;
|
---|
67 | if ( dp<0 ) {
|
---|
68 | *s++ = '-' ; dp= -dp ;
|
---|
69 | } else {
|
---|
70 | *s++ = '+' ;
|
---|
71 | }
|
---|
72 | if (dp >= 100) {
|
---|
73 | *s++ = '0' + (dp / 100);
|
---|
74 | dp %= 100;
|
---|
75 | }
|
---|
76 | *s++ = '0' + (dp/10);
|
---|
77 | *s++ = '0' + (dp%10);
|
---|
78 | return s;
|
---|
79 | }
|
---|
80 |
|
---|
81 | #define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
|
---|
82 | #define LOW_EXP -4
|
---|
83 | #define USE_EXP(exp, ndigits) (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
|
---|
84 |
|
---|
85 | static char *
|
---|
86 | _gcvt(long double value, int ndigit, char *s, int flags)
|
---|
87 | {
|
---|
88 | int sign, dp;
|
---|
89 | register char *s1, *s2;
|
---|
90 | register int i;
|
---|
91 | register int nndigit = ndigit;
|
---|
92 |
|
---|
93 | s1 = _ecvt(value, ndigit, &dp, &sign);
|
---|
94 | s2 = s;
|
---|
95 | if (sign) *s2++ = '-';
|
---|
96 | else if (flags & FL_SIGN)
|
---|
97 | *s2++ = '+';
|
---|
98 | else if (flags & FL_SPACE)
|
---|
99 | *s2++ = ' ';
|
---|
100 |
|
---|
101 | if (!(flags & FL_ALT))
|
---|
102 | for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
|
---|
103 | nndigit--;
|
---|
104 |
|
---|
105 | if (USE_EXP(dp,ndigit)) {
|
---|
106 | /* Use E format */
|
---|
107 | dp--;
|
---|
108 | *s2++ = *s1++;
|
---|
109 | if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
|
---|
110 | while (--nndigit > 0) *s2++ = *s1++;
|
---|
111 | *s2++ = 'e';
|
---|
112 | if (dp < 0) {
|
---|
113 | *s2++ = '-';
|
---|
114 | dp = -dp;
|
---|
115 | }
|
---|
116 | else *s2++ = '+';
|
---|
117 | s2 += NDIGINEXP(dp);
|
---|
118 | *s2 = 0;
|
---|
119 | for (i = NDIGINEXP(dp); i > 0; i--) {
|
---|
120 | *--s2 = dp % 10 + '0';
|
---|
121 | dp /= 10;
|
---|
122 | }
|
---|
123 | return s;
|
---|
124 | }
|
---|
125 | /* Use f format */
|
---|
126 | if (dp <= 0) {
|
---|
127 | if (*s1 != '0') {
|
---|
128 | /* otherwise the whole number is 0 */
|
---|
129 | *s2++ = '0';
|
---|
130 | *s2++ = '.';
|
---|
131 | }
|
---|
132 | while (dp < 0) {
|
---|
133 | dp++;
|
---|
134 | *s2++ = '0';
|
---|
135 | }
|
---|
136 | }
|
---|
137 | for (i = 1; i <= nndigit; i++) {
|
---|
138 | *s2++ = *s1++;
|
---|
139 | if (i == dp) *s2++ = '.';
|
---|
140 | }
|
---|
141 | if (i <= dp) {
|
---|
142 | while (i++ <= dp) *s2++ = '0';
|
---|
143 | *s2++ = '.';
|
---|
144 | }
|
---|
145 | if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
|
---|
146 | *s2 = '\0';
|
---|
147 | return s;
|
---|
148 | }
|
---|
149 |
|
---|
150 | char *
|
---|
151 | _f_print(va_list *ap, int flags, char *s, char c, int precision)
|
---|
152 | {
|
---|
153 | register char *old_s = s;
|
---|
154 | long double ld_val;
|
---|
155 |
|
---|
156 | if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, long double);
|
---|
157 | else ld_val = (long double) va_arg(*ap, double);
|
---|
158 |
|
---|
159 | switch(c) {
|
---|
160 | case 'f':
|
---|
161 | s = _pfloat(ld_val, s, precision, flags);
|
---|
162 | break;
|
---|
163 | case 'e':
|
---|
164 | case 'E':
|
---|
165 | s = _pscien(ld_val, s, precision , flags);
|
---|
166 | break;
|
---|
167 | case 'g':
|
---|
168 | case 'G':
|
---|
169 | s = _gcvt(ld_val, precision, s, flags);
|
---|
170 | s += strlen(s);
|
---|
171 | break;
|
---|
172 | }
|
---|
173 | if ( c == 'E' || c == 'G') {
|
---|
174 | while (*old_s && *old_s != 'e') old_s++;
|
---|
175 | if (*old_s == 'e') *old_s = 'E';
|
---|
176 | }
|
---|
177 | return s;
|
---|
178 | }
|
---|
179 | #endif /* NOFLOAT */
|
---|
180 | /* $Header: /cvsup/minix/src/lib/gnu/ieee_float/fphook.c,v 1.1 2005/10/10 15:28:15 beng Exp $ */
|
---|
181 |
|
---|
182 | #include <stdlib.h>
|
---|
183 | #include "../ansi/ext_fmt.h"
|
---|
184 |
|
---|
185 | void _str_ext_cvt(const char *s, char **ss, struct EXTEND *e);
|
---|
186 | double _ext_dbl_cvt(struct EXTEND *e);
|
---|
187 |
|
---|
188 | double
|
---|
189 | strtod(const char *p, char **pp)
|
---|
190 | {
|
---|
191 | struct EXTEND e;
|
---|
192 |
|
---|
193 | _str_ext_cvt(p, pp, &e);
|
---|
194 | return _ext_dbl_cvt(&e);
|
---|
195 | }
|
---|