Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: fusl/src/internal/floatscan.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <stdint.h> 1 #include <stdint.h>
2 #include <stdio.h> 2 #include <stdio.h>
3 #include <math.h> 3 #include <math.h>
4 #include <float.h> 4 #include <float.h>
5 #include <limits.h> 5 #include <limits.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <ctype.h> 7 #include <ctype.h>
8 8
9 #include "shgetc.h" 9 #include "shgetc.h"
10 #include "floatscan.h" 10 #include "floatscan.h"
(...skipping 13 matching lines...) Expand all
24 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 24 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
25 25
26 #define LD_B1B_DIG 4 26 #define LD_B1B_DIG 4
27 #define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191 27 #define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191
28 #define KMAX 2048 28 #define KMAX 2048
29 29
30 #else 30 #else
31 #error Unsupported long double representation 31 #error Unsupported long double representation
32 #endif 32 #endif
33 33
34 #define MASK (KMAX-1) 34 #define MASK (KMAX - 1)
35 35
36 #define CONCAT2(x,y) x ## y 36 #define CONCAT2(x, y) x##y
37 #define CONCAT(x,y) CONCAT2(x,y) 37 #define CONCAT(x, y) CONCAT2(x, y)
38 38
39 static long long scanexp(FILE *f, int pok) 39 static long long scanexp(FILE* f, int pok) {
40 { 40 int c;
41 » int c; 41 int x;
42 » int x; 42 long long y;
43 » long long y; 43 int neg = 0;
44 » int neg = 0; 44
45 » 45 c = shgetc(f);
46 » c = shgetc(f); 46 if (c == '+' || c == '-') {
47 » if (c=='+' || c=='-') { 47 neg = (c == '-');
48 » » neg = (c=='-'); 48 c = shgetc(f);
49 » » c = shgetc(f); 49 if (c - '0' >= 10U && pok)
50 » » if (c-'0'>=10U && pok) shunget(f); 50 shunget(f);
51 » } 51 }
52 » if (c-'0'>=10U) { 52 if (c - '0' >= 10U) {
53 » » shunget(f); 53 shunget(f);
54 » » return LLONG_MIN; 54 return LLONG_MIN;
55 » } 55 }
56 » for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f)) 56 for (x = 0; c - '0' < 10U && x < INT_MAX / 10; c = shgetc(f))
57 » » x = 10*x + c-'0'; 57 x = 10 * x + c - '0';
58 » for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f)) 58 for (y = x; c - '0' < 10U && y < LLONG_MAX / 100; c = shgetc(f))
59 » » y = 10*y + c-'0'; 59 y = 10 * y + c - '0';
60 » for (; c-'0'<10U; c = shgetc(f)); 60 for (; c - '0' < 10U; c = shgetc(f))
61 » shunget(f); 61 ;
62 » return neg ? -y : y; 62 shunget(f);
63 return neg ? -y : y;
63 } 64 }
64 65
65 66 static long double decfloat(FILE* f,
66 static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po k) 67 int c,
67 { 68 int bits,
68 uint32_t x[KMAX]; 69 int emin,
69 static const uint32_t th[] = { LD_B1B_MAX }; 70 int sign,
70 int i, j, k, a, z; 71 int pok) {
71 long long lrp=0, dc=0; 72 uint32_t x[KMAX];
72 long long e10=0; 73 static const uint32_t th[] = {LD_B1B_MAX};
73 int lnz = 0; 74 int i, j, k, a, z;
74 int gotdig = 0, gotrad = 0; 75 long long lrp = 0, dc = 0;
75 int rp; 76 long long e10 = 0;
76 int e2; 77 int lnz = 0;
77 int emax = -emin-bits+3; 78 int gotdig = 0, gotrad = 0;
78 int denormal = 0; 79 int rp;
79 long double y; 80 int e2;
80 long double frac=0; 81 int emax = -emin - bits + 3;
81 long double bias=0; 82 int denormal = 0;
82 static const int p10s[] = { 10, 100, 1000, 10000, 83 long double y;
83 100000, 1000000, 10000000, 100000000 }; 84 long double frac = 0;
84 85 long double bias = 0;
85 j=0; 86 static const int p10s[] = {10, 100, 1000, 10000,
86 k=0; 87 100000, 1000000, 10000000, 100000000};
87 88
88 /* Don't let leading zeros consume buffer space */ 89 j = 0;
89 for (; c=='0'; c = shgetc(f)) gotdig=1; 90 k = 0;
90 if (c=='.') { 91
91 gotrad = 1; 92 /* Don't let leading zeros consume buffer space */
92 for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--; 93 for (; c == '0'; c = shgetc(f))
93 } 94 gotdig = 1;
94 95 if (c == '.') {
95 x[0] = 0; 96 gotrad = 1;
96 for (; c-'0'<10U || c=='.'; c = shgetc(f)) { 97 for (c = shgetc(f); c == '0'; c = shgetc(f))
97 if (c == '.') { 98 gotdig = 1, lrp--;
98 if (gotrad) break; 99 }
99 gotrad = 1; 100
100 lrp = dc; 101 x[0] = 0;
101 } else if (k < KMAX-3) { 102 for (; c - '0' < 10U || c == '.'; c = shgetc(f)) {
102 dc++; 103 if (c == '.') {
103 if (c!='0') lnz = dc; 104 if (gotrad)
104 if (j) x[k] = x[k]*10 + c-'0'; 105 break;
105 else x[k] = c-'0'; 106 gotrad = 1;
106 if (++j==9) { 107 lrp = dc;
107 k++; 108 } else if (k < KMAX - 3) {
108 j=0; 109 dc++;
109 } 110 if (c != '0')
110 gotdig=1; 111 lnz = dc;
111 } else { 112 if (j)
112 dc++; 113 x[k] = x[k] * 10 + c - '0';
113 if (c!='0') x[KMAX-4] |= 1; 114 else
114 } 115 x[k] = c - '0';
115 } 116 if (++j == 9) {
116 if (!gotrad) lrp=dc; 117 k++;
117 118 j = 0;
118 if (gotdig && (c|32)=='e') { 119 }
119 e10 = scanexp(f, pok); 120 gotdig = 1;
120 if (e10 == LLONG_MIN) { 121 } else {
121 if (pok) { 122 dc++;
122 shunget(f); 123 if (c != '0')
123 } else { 124 x[KMAX - 4] |= 1;
124 shlim(f, 0); 125 }
125 return 0; 126 }
126 } 127 if (!gotrad)
127 e10 = 0; 128 lrp = dc;
128 } 129
129 lrp += e10; 130 if (gotdig && (c | 32) == 'e') {
130 } else if (c>=0) { 131 e10 = scanexp(f, pok);
131 shunget(f); 132 if (e10 == LLONG_MIN) {
132 } 133 if (pok) {
133 if (!gotdig) { 134 shunget(f);
134 errno = EINVAL; 135 } else {
135 shlim(f, 0); 136 shlim(f, 0);
136 return 0; 137 return 0;
137 } 138 }
138 139 e10 = 0;
139 /* Handle zero specially to avoid nasty special cases later */ 140 }
140 if (!x[0]) return sign * 0.0; 141 lrp += e10;
141 142 } else if (c >= 0) {
142 /* Optimize small integers (w/no exponent) and over/under-flow */ 143 shunget(f);
143 if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0)) 144 }
144 return sign * (long double)x[0]; 145 if (!gotdig) {
145 if (lrp > -emin/2) { 146 errno = EINVAL;
146 errno = ERANGE; 147 shlim(f, 0);
147 return sign * LDBL_MAX * LDBL_MAX; 148 return 0;
148 } 149 }
149 if (lrp < emin-2*LDBL_MANT_DIG) { 150
150 errno = ERANGE; 151 /* Handle zero specially to avoid nasty special cases later */
151 return sign * LDBL_MIN * LDBL_MIN; 152 if (!x[0])
152 } 153 return sign * 0.0;
153 154
154 /* Align incomplete final B1B digit */ 155 /* Optimize small integers (w/no exponent) and over/under-flow */
155 if (j) { 156 if (lrp == dc && dc < 10 && (bits > 30 || x[0] >> bits == 0))
156 for (; j<9; j++) x[k]*=10; 157 return sign * (long double)x[0];
157 k++; 158 if (lrp > -emin / 2) {
158 j=0; 159 errno = ERANGE;
159 } 160 return sign * LDBL_MAX * LDBL_MAX;
160 161 }
161 a = 0; 162 if (lrp < emin - 2 * LDBL_MANT_DIG) {
162 z = k; 163 errno = ERANGE;
163 e2 = 0; 164 return sign * LDBL_MIN * LDBL_MIN;
164 rp = lrp; 165 }
165 166
166 /* Optimize small to mid-size integers (even in exp. notation) */ 167 /* Align incomplete final B1B digit */
167 if (lnz<9 && lnz<=rp && rp < 18) { 168 if (j) {
168 if (rp == 9) return sign * (long double)x[0]; 169 for (; j < 9; j++)
169 if (rp < 9) return sign * (long double)x[0] / p10s[8-rp]; 170 x[k] *= 10;
170 int bitlim = bits-3*(int)(rp-9); 171 k++;
171 if (bitlim>30 || x[0]>>bitlim==0) 172 j = 0;
172 return sign * (long double)x[0] * p10s[rp-10]; 173 }
173 } 174
174 175 a = 0;
175 /* Align radix point to B1B digit boundary */ 176 z = k;
176 if (rp % 9) { 177 e2 = 0;
177 int rpm9 = rp>=0 ? rp%9 : rp%9+9; 178 rp = lrp;
178 int p10 = p10s[8-rpm9]; 179
179 uint32_t carry = 0; 180 /* Optimize small to mid-size integers (even in exp. notation) */
180 for (k=a; k!=z; k++) { 181 if (lnz < 9 && lnz <= rp && rp < 18) {
181 uint32_t tmp = x[k] % p10; 182 if (rp == 9)
182 x[k] = x[k]/p10 + carry; 183 return sign * (long double)x[0];
183 carry = 1000000000/p10 * tmp; 184 if (rp < 9)
184 if (k==a && !x[k]) { 185 return sign * (long double)x[0] / p10s[8 - rp];
185 a = (a+1 & MASK); 186 int bitlim = bits - 3 * (int)(rp - 9);
186 rp -= 9; 187 if (bitlim > 30 || x[0] >> bitlim == 0)
187 } 188 return sign * (long double)x[0] * p10s[rp - 10];
188 } 189 }
189 if (carry) x[z++] = carry; 190
190 rp += 9-rpm9; 191 /* Align radix point to B1B digit boundary */
191 } 192 if (rp % 9) {
192 193 int rpm9 = rp >= 0 ? rp % 9 : rp % 9 + 9;
193 /* Upscale until desired number of bits are left of radix point */ 194 int p10 = p10s[8 - rpm9];
194 while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) { 195 uint32_t carry = 0;
195 uint32_t carry = 0; 196 for (k = a; k != z; k++) {
196 e2 -= 29; 197 uint32_t tmp = x[k] % p10;
197 for (k=(z-1 & MASK); ; k=(k-1 & MASK)) { 198 x[k] = x[k] / p10 + carry;
198 uint64_t tmp = ((uint64_t)x[k] << 29) + carry; 199 carry = 1000000000 / p10 * tmp;
199 if (tmp > 1000000000) { 200 if (k == a && !x[k]) {
200 carry = tmp / 1000000000; 201 a = (a + 1 & MASK);
201 x[k] = tmp % 1000000000; 202 rp -= 9;
202 } else { 203 }
203 carry = 0; 204 }
204 x[k] = tmp; 205 if (carry)
205 } 206 x[z++] = carry;
206 if (k==(z-1 & MASK) && k!=a && !x[k]) z = k; 207 rp += 9 - rpm9;
207 if (k==a) break; 208 }
208 } 209
209 if (carry) { 210 /* Upscale until desired number of bits are left of radix point */
210 rp += 9; 211 while (rp < 9 * LD_B1B_DIG || (rp == 9 * LD_B1B_DIG && x[a] < th[0])) {
211 a = (a-1 & MASK); 212 uint32_t carry = 0;
212 if (a == z) { 213 e2 -= 29;
213 z = (z-1 & MASK); 214 for (k = (z - 1 & MASK);; k = (k - 1 & MASK)) {
214 x[z-1 & MASK] |= x[z]; 215 uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
215 } 216 if (tmp > 1000000000) {
216 x[a] = carry; 217 carry = tmp / 1000000000;
217 } 218 x[k] = tmp % 1000000000;
218 } 219 } else {
219 220 carry = 0;
220 /* Downscale until exactly number of bits are left of radix point */ 221 x[k] = tmp;
221 for (;;) { 222 }
222 uint32_t carry = 0; 223 if (k == (z - 1 & MASK) && k != a && !x[k])
223 int sh = 1; 224 z = k;
224 for (i=0; i<LD_B1B_DIG; i++) { 225 if (k == a)
225 k = (a+i & MASK); 226 break;
226 if (k == z || x[k] < th[i]) { 227 }
227 i=LD_B1B_DIG; 228 if (carry) {
228 break; 229 rp += 9;
229 } 230 a = (a - 1 & MASK);
230 if (x[a+i & MASK] > th[i]) break; 231 if (a == z) {
231 } 232 z = (z - 1 & MASK);
232 if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break; 233 x[z - 1 & MASK] |= x[z];
233 /* FIXME: find a way to compute optimal sh */ 234 }
234 if (rp > 9+9*LD_B1B_DIG) sh = 9; 235 x[a] = carry;
235 e2 += sh; 236 }
236 for (k=a; k!=z; k=(k+1 & MASK)) { 237 }
237 uint32_t tmp = x[k] & (1<<sh)-1; 238
238 x[k] = (x[k]>>sh) + carry; 239 /* Downscale until exactly number of bits are left of radix point */
239 carry = (1000000000>>sh) * tmp; 240 for (;;) {
240 if (k==a && !x[k]) { 241 uint32_t carry = 0;
241 a = (a+1 & MASK); 242 int sh = 1;
242 i--; 243 for (i = 0; i < LD_B1B_DIG; i++) {
243 rp -= 9; 244 k = (a + i & MASK);
244 } 245 if (k == z || x[k] < th[i]) {
245 } 246 i = LD_B1B_DIG;
246 if (carry) { 247 break;
247 if ((z+1 & MASK) != a) { 248 }
248 x[z] = carry; 249 if (x[a + i & MASK] > th[i])
249 z = (z+1 & MASK); 250 break;
250 } else x[z-1 & MASK] |= 1; 251 }
251 } 252 if (i == LD_B1B_DIG && rp == 9 * LD_B1B_DIG)
252 } 253 break;
253 254 /* FIXME: find a way to compute optimal sh */
254 /* Assemble desired bits into floating point variable */ 255 if (rp > 9 + 9 * LD_B1B_DIG)
255 for (y=i=0; i<LD_B1B_DIG; i++) { 256 sh = 9;
256 if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0; 257 e2 += sh;
257 y = 1000000000.0L * y + x[a+i & MASK]; 258 for (k = a; k != z; k = (k + 1 & MASK)) {
258 } 259 uint32_t tmp = x[k] & (1 << sh) - 1;
259 260 x[k] = (x[k] >> sh) + carry;
260 y *= sign; 261 carry = (1000000000 >> sh) * tmp;
261 262 if (k == a && !x[k]) {
262 /* Limit precision for denormal results */ 263 a = (a + 1 & MASK);
263 if (bits > LDBL_MANT_DIG+e2-emin) { 264 i--;
264 bits = LDBL_MANT_DIG+e2-emin; 265 rp -= 9;
265 if (bits<0) bits=0; 266 }
266 denormal = 1; 267 }
267 } 268 if (carry) {
268 269 if ((z + 1 & MASK) != a) {
269 /* Calculate bias term to force rounding, move out lower bits */ 270 x[z] = carry;
270 if (bits < LDBL_MANT_DIG) { 271 z = (z + 1 & MASK);
271 bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y); 272 } else
272 frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits)); 273 x[z - 1 & MASK] |= 1;
273 y -= frac; 274 }
274 y += bias; 275 }
275 } 276
276 277 /* Assemble desired bits into floating point variable */
277 /* Process tail of decimal input so it can affect rounding */ 278 for (y = i = 0; i < LD_B1B_DIG; i++) {
278 if ((a+i & MASK) != z) { 279 if ((a + i & MASK) == z)
279 uint32_t t = x[a+i & MASK]; 280 x[(z = (z + 1 & MASK)) - 1] = 0;
280 if (t < 500000000 && (t || (a+i+1 & MASK) != z)) 281 y = 1000000000.0L * y + x[a + i & MASK];
281 frac += 0.25*sign; 282 }
282 else if (t > 500000000) 283
283 frac += 0.75*sign; 284 y *= sign;
284 else if (t == 500000000) { 285
285 if ((a+i+1 & MASK) == z) 286 /* Limit precision for denormal results */
286 frac += 0.5*sign; 287 if (bits > LDBL_MANT_DIG + e2 - emin) {
287 else 288 bits = LDBL_MANT_DIG + e2 - emin;
288 frac += 0.75*sign; 289 if (bits < 0)
289 } 290 bits = 0;
290 if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1)) 291 denormal = 1;
291 frac++; 292 }
292 } 293
293 294 /* Calculate bias term to force rounding, move out lower bits */
294 y += frac; 295 if (bits < LDBL_MANT_DIG) {
295 y -= bias; 296 bias = copysignl(scalbn(1, 2 * LDBL_MANT_DIG - bits - 1), y);
296 297 frac = fmodl(y, scalbn(1, LDBL_MANT_DIG - bits));
297 if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) { 298 y -= frac;
298 if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) { 299 y += bias;
299 if (denormal && bits==LDBL_MANT_DIG+e2-emin) 300 }
300 denormal = 0; 301
301 y *= 0.5; 302 /* Process tail of decimal input so it can affect rounding */
302 e2++; 303 if ((a + i & MASK) != z) {
303 } 304 uint32_t t = x[a + i & MASK];
304 if (e2+LDBL_MANT_DIG>emax || (denormal && frac)) 305 if (t < 500000000 && (t || (a + i + 1 & MASK) != z))
305 errno = ERANGE; 306 frac += 0.25 * sign;
306 } 307 else if (t > 500000000)
307 308 frac += 0.75 * sign;
308 return scalbnl(y, e2); 309 else if (t == 500000000) {
310 if ((a + i + 1 & MASK) == z)
311 frac += 0.5 * sign;
312 else
313 frac += 0.75 * sign;
314 }
315 if (LDBL_MANT_DIG - bits >= 2 && !fmodl(frac, 1))
316 frac++;
317 }
318
319 y += frac;
320 y -= bias;
321
322 if ((e2 + LDBL_MANT_DIG & INT_MAX) > emax - 5) {
323 if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) {
324 if (denormal && bits == LDBL_MANT_DIG + e2 - emin)
325 denormal = 0;
326 y *= 0.5;
327 e2++;
328 }
329 if (e2 + LDBL_MANT_DIG > emax || (denormal && frac))
330 errno = ERANGE;
331 }
332
333 return scalbnl(y, e2);
309 } 334 }
310 335
311 static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok) 336 static long double hexfloat(FILE* f, int bits, int emin, int sign, int pok) {
312 { 337 uint32_t x = 0;
313 » uint32_t x = 0; 338 long double y = 0;
314 » long double y = 0; 339 long double scale = 1;
315 » long double scale = 1; 340 long double bias = 0;
316 » long double bias = 0; 341 int gottail = 0, gotrad = 0, gotdig = 0;
317 » int gottail = 0, gotrad = 0, gotdig = 0; 342 long long rp = 0;
318 » long long rp = 0; 343 long long dc = 0;
319 » long long dc = 0; 344 long long e2 = 0;
320 » long long e2 = 0; 345 int d;
321 » int d; 346 int c;
322 » int c; 347
323 348 c = shgetc(f);
324 » c = shgetc(f); 349
325 350 /* Skip leading zeros */
326 » /* Skip leading zeros */ 351 for (; c == '0'; c = shgetc(f))
327 » for (; c=='0'; c = shgetc(f)) gotdig = 1; 352 gotdig = 1;
328 353
329 » if (c=='.') { 354 if (c == '.') {
330 » » gotrad = 1; 355 gotrad = 1;
331 » » c = shgetc(f); 356 c = shgetc(f);
332 » » /* Count zeros after the radix point before significand */ 357 /* Count zeros after the radix point before significand */
333 » » for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1; 358 for (rp = 0; c == '0'; c = shgetc(f), rp--)
334 » } 359 gotdig = 1;
335 360 }
336 » for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) { 361
337 » » if (c=='.') { 362 for (; c - '0' < 10U || (c | 32) - 'a' < 6U || c == '.'; c = shgetc(f)) {
338 » » » if (gotrad) break; 363 if (c == '.') {
339 » » » rp = dc; 364 if (gotrad)
340 » » » gotrad = 1; 365 break;
341 » » } else { 366 rp = dc;
342 » » » gotdig = 1; 367 gotrad = 1;
343 » » » if (c > '9') d = (c|32)+10-'a'; 368 } else {
344 » » » else d = c-'0'; 369 gotdig = 1;
345 » » » if (dc<8) { 370 if (c > '9')
346 » » » » x = x*16 + d; 371 d = (c | 32) + 10 - 'a';
347 » » » } else if (dc < LDBL_MANT_DIG/4+1) { 372 else
348 » » » » y += d*(scale/=16); 373 d = c - '0';
349 » » » } else if (d && !gottail) { 374 if (dc < 8) {
350 » » » » y += 0.5*scale; 375 x = x * 16 + d;
351 » » » » gottail = 1; 376 } else if (dc < LDBL_MANT_DIG / 4 + 1) {
352 » » » } 377 y += d * (scale /= 16);
353 » » » dc++; 378 } else if (d && !gottail) {
354 » » } 379 y += 0.5 * scale;
355 » } 380 gottail = 1;
356 » if (!gotdig) { 381 }
357 » » shunget(f); 382 dc++;
358 » » if (pok) { 383 }
359 » » » shunget(f); 384 }
360 » » » if (gotrad) shunget(f); 385 if (!gotdig) {
361 » » } else { 386 shunget(f);
362 » » » shlim(f, 0); 387 if (pok) {
363 » » } 388 shunget(f);
364 » » return sign * 0.0; 389 if (gotrad)
365 » } 390 shunget(f);
366 » if (!gotrad) rp = dc; 391 } else {
367 » while (dc<8) x *= 16, dc++; 392 shlim(f, 0);
368 » if ((c|32)=='p') { 393 }
369 » » e2 = scanexp(f, pok); 394 return sign * 0.0;
370 » » if (e2 == LLONG_MIN) { 395 }
371 » » » if (pok) { 396 if (!gotrad)
372 » » » » shunget(f); 397 rp = dc;
373 » » » } else { 398 while (dc < 8)
374 » » » » shlim(f, 0); 399 x *= 16, dc++;
375 » » » » return 0; 400 if ((c | 32) == 'p') {
376 » » » } 401 e2 = scanexp(f, pok);
377 » » » e2 = 0; 402 if (e2 == LLONG_MIN) {
378 » » } 403 if (pok) {
379 » } else { 404 shunget(f);
380 » » shunget(f); 405 } else {
381 » } 406 shlim(f, 0);
382 » e2 += 4*rp - 32; 407 return 0;
383 408 }
384 » if (!x) return sign * 0.0; 409 e2 = 0;
385 » if (e2 > -emin) { 410 }
386 » » errno = ERANGE; 411 } else {
387 » » return sign * LDBL_MAX * LDBL_MAX; 412 shunget(f);
388 » } 413 }
389 » if (e2 < emin-2*LDBL_MANT_DIG) { 414 e2 += 4 * rp - 32;
390 » » errno = ERANGE; 415
391 » » return sign * LDBL_MIN * LDBL_MIN; 416 if (!x)
392 » } 417 return sign * 0.0;
393 418 if (e2 > -emin) {
394 » while (x < 0x80000000) { 419 errno = ERANGE;
395 » » if (y>=0.5) { 420 return sign * LDBL_MAX * LDBL_MAX;
396 » » » x += x + 1; 421 }
397 » » » y += y - 1; 422 if (e2 < emin - 2 * LDBL_MANT_DIG) {
398 » » } else { 423 errno = ERANGE;
399 » » » x += x; 424 return sign * LDBL_MIN * LDBL_MIN;
400 » » » y += y; 425 }
401 » » } 426
402 » » e2--; 427 while (x < 0x80000000) {
403 » } 428 if (y >= 0.5) {
404 429 x += x + 1;
405 » if (bits > 32+e2-emin) { 430 y += y - 1;
406 » » bits = 32+e2-emin; 431 } else {
407 » » if (bits<0) bits=0; 432 x += x;
408 » } 433 y += y;
409 434 }
410 » if (bits < LDBL_MANT_DIG) 435 e2--;
411 » » bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign); 436 }
412 437
413 » if (bits<32 && y && !(x&1)) x++, y=0; 438 if (bits > 32 + e2 - emin) {
414 439 bits = 32 + e2 - emin;
415 » y = bias + sign*(long double)x + sign*y; 440 if (bits < 0)
416 » y -= bias; 441 bits = 0;
417 442 }
418 » if (!y) errno = ERANGE; 443
419 444 if (bits < LDBL_MANT_DIG)
420 » return scalbnl(y, e2); 445 bias = copysignl(scalbn(1, 32 + LDBL_MANT_DIG - bits - 1), sign);
446
447 if (bits < 32 && y && !(x & 1))
448 x++, y = 0;
449
450 y = bias + sign * (long double)x + sign * y;
451 y -= bias;
452
453 if (!y)
454 errno = ERANGE;
455
456 return scalbnl(y, e2);
421 } 457 }
422 458
423 long double __floatscan(FILE *f, int prec, int pok) 459 long double __floatscan(FILE* f, int prec, int pok) {
424 { 460 int sign = 1;
425 » int sign = 1; 461 size_t i;
426 » size_t i; 462 int bits;
427 » int bits; 463 int emin;
428 » int emin; 464 int c;
429 » int c; 465
430 466 switch (prec) {
431 » switch (prec) { 467 case 0:
432 » case 0: 468 bits = FLT_MANT_DIG;
433 » » bits = FLT_MANT_DIG; 469 emin = FLT_MIN_EXP - bits;
434 » » emin = FLT_MIN_EXP-bits; 470 break;
435 » » break; 471 case 1:
436 » case 1: 472 bits = DBL_MANT_DIG;
437 » » bits = DBL_MANT_DIG; 473 emin = DBL_MIN_EXP - bits;
438 » » emin = DBL_MIN_EXP-bits; 474 break;
439 » » break; 475 case 2:
440 » case 2: 476 bits = LDBL_MANT_DIG;
441 » » bits = LDBL_MANT_DIG; 477 emin = LDBL_MIN_EXP - bits;
442 » » emin = LDBL_MIN_EXP-bits; 478 break;
443 » » break; 479 default:
444 » default: 480 return 0;
445 » » return 0; 481 }
446 » } 482
447 483 while (isspace((c = shgetc(f))))
448 » while (isspace((c=shgetc(f)))); 484 ;
449 485
450 » if (c=='+' || c=='-') { 486 if (c == '+' || c == '-') {
451 » » sign -= 2*(c=='-'); 487 sign -= 2 * (c == '-');
452 » » c = shgetc(f); 488 c = shgetc(f);
453 » } 489 }
454 490
455 » for (i=0; i<8 && (c|32)=="infinity"[i]; i++) 491 for (i = 0; i < 8 && (c | 32) == "infinity"[i]; i++)
456 » » if (i<7) c = shgetc(f); 492 if (i < 7)
457 » if (i==3 || i==8 || (i>3 && pok)) { 493 c = shgetc(f);
458 » » if (i!=8) { 494 if (i == 3 || i == 8 || (i > 3 && pok)) {
459 » » » shunget(f); 495 if (i != 8) {
460 » » » if (pok) for (; i>3; i--) shunget(f); 496 shunget(f);
461 » » } 497 if (pok)
462 » » return sign * INFINITY; 498 for (; i > 3; i--)
463 » } 499 shunget(f);
464 » if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++) 500 }
465 » » if (i<2) c = shgetc(f); 501 return sign * INFINITY;
466 » if (i==3) { 502 }
467 » » if (shgetc(f) != '(') { 503 if (!i)
468 » » » shunget(f); 504 for (i = 0; i < 3 && (c | 32) == "nan"[i]; i++)
469 » » » return NAN; 505 if (i < 2)
470 » » } 506 c = shgetc(f);
471 » » for (i=1; ; i++) { 507 if (i == 3) {
472 » » » c = shgetc(f); 508 if (shgetc(f) != '(') {
473 » » » if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_') 509 shunget(f);
474 » » » » continue; 510 return NAN;
475 » » » if (c==')') return NAN; 511 }
476 » » » shunget(f); 512 for (i = 1;; i++) {
477 » » » if (!pok) { 513 c = shgetc(f);
478 » » » » errno = EINVAL; 514 if (c - '0' < 10U || c - 'A' < 26U || c - 'a' < 26U || c == '_')
479 » » » » shlim(f, 0); 515 continue;
480 » » » » return 0; 516 if (c == ')')
481 » » » } 517 return NAN;
482 » » » while (i--) shunget(f); 518 shunget(f);
483 » » » return NAN; 519 if (!pok) {
484 » » } 520 errno = EINVAL;
485 » » return NAN; 521 shlim(f, 0);
486 » } 522 return 0;
487 523 }
488 » if (i) { 524 while (i--)
489 » » shunget(f); 525 shunget(f);
490 » » errno = EINVAL; 526 return NAN;
491 » » shlim(f, 0); 527 }
492 » » return 0; 528 return NAN;
493 » } 529 }
494 530
495 » if (c=='0') { 531 if (i) {
496 » » c = shgetc(f); 532 shunget(f);
497 » » if ((c|32) == 'x') 533 errno = EINVAL;
498 » » » return hexfloat(f, bits, emin, sign, pok); 534 shlim(f, 0);
499 » » shunget(f); 535 return 0;
500 » » c = '0'; 536 }
501 » } 537
502 538 if (c == '0') {
503 » return decfloat(f, c, bits, emin, sign, pok); 539 c = shgetc(f);
540 if ((c | 32) == 'x')
541 return hexfloat(f, bits, emin, sign, pok);
542 shunget(f);
543 c = '0';
544 }
545
546 return decfloat(f, c, bits, emin, sign, pok);
504 } 547 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698