source: trunk/minix/lib/gnu/ieee_float/fphook.c@ 10

Last change on this file since 10 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.7 KB
Line 
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"
10int _fp_hook = 1;
11
12static 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
45static 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
85static 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
150char *
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
185void _str_ext_cvt(const char *s, char **ss, struct EXTEND *e);
186double _ext_dbl_cvt(struct EXTEND *e);
187
188double
189strtod(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}
Note: See TracBrowser for help on using the repository browser.