1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #if __STDC__
23 #include "FEATURE/standards"
24 #endif
25 #include "sfhdr.h"
26
27 /* Convert a floating point value to ASCII.
28 **
29 ** Written by Kiem-Phong Vo and Glenn Fowler (SFFMT_AFORMAT)
30 */
31
32 static char *lc_inf = "inf", *uc_inf = "INF";
33 static char *lc_nan = "nan", *uc_nan = "NAN";
34 static char *Zero = "0";
35 #define SF_INF ((_Sfi = 3), strlcpy(buf, (format & SFFMT_UPPER) ? uc_inf : lc_inf, size), buf)
36 #define SF_NAN ((_Sfi = 3), strlcpy(buf, (format & SFFMT_UPPER) ? uc_nan : lc_nan, size), buf)
37 #define SF_ZERO ((_Sfi = 1), strlcpy(buf, Zero, size), buf)
38 #define SF_INTPART (SF_IDIGITS/2)
39
40 #if !_lib_isnan
41 #undef isnan
42 #undef isnanl
43 #if _lib_fpclassify
44 #define isnan(n) (fpclassify(n)==FP_NAN)
45 #define isnanl(n) (fpclassify(n)==FP_NAN)
46 #else
47 #error "This is an invalid test for NaN"
48 #define isnan(n) (memcmp((void*)&n,(void*)&_Sfdnan,sizeof(n))==0)
49 #define isnanl(n) (memcmp((void*)&n,(void*)&_Sflnan,sizeof(n))==0)
50 #endif
51 #else
52 #if !_lib_isnanl
53 #undef isnanl
54 #define isnanl(n) isnan(n)
55 #endif
56 #endif
57
58 #if !_lib_signbit
59 #if !_ast_fltmax_double
neg0ld(Sfdouble_t f)60 static int neg0ld(Sfdouble_t f)
61 {
62 Sfdouble_t z = 0;
63 z = -z;
64 return !memcmp(&f, &z, sizeof(f));
65 }
66 #endif
neg0d(double f)67 static int neg0d(double f)
68 {
69 double z = 0;
70 z = -z;
71 return !memcmp(&f, &z, sizeof(f));
72 }
73 #endif
74
75 #if ULONG_DIG && ULONG_DIG < (DBL_DIG-1)
76 #define CVT_LDBL_INT long
77 #define CVT_LDBL_MAXINT LONG_MAX
78 #else
79 #if UINT_DIG && UINT_DIG < (DBL_DIG-1)
80 #define CVT_LDBL_INT int
81 #define CVT_LDBL_MAXINT INT_MAX
82 #else
83 #define CVT_LDBL_INT long
84 #define CVT_LDBL_MAXINT SF_MAXLONG
85 #endif
86 #endif
87
88 #if ULONG_DIG && ULONG_DIG < (DBL_DIG-1)
89 #define CVT_DBL_INT long
90 #define CVT_DBL_MAXINT LONG_MAX
91 #else
92 #if UINT_DIG && UINT_DIG < (DBL_DIG-1)
93 #define CVT_DBL_INT int
94 #define CVT_DBL_MAXINT INT_MAX
95 #else
96 #define CVT_DBL_INT long
97 #define CVT_DBL_MAXINT SF_MAXLONG
98 #endif
99 #endif
100
101 #if __STD_C
_sfcvt(Void_t * vp,char * buf,size_t size,int n_digit,int * decpt,int * sign,int * len,int format)102 char* _sfcvt(Void_t* vp, char* buf, size_t size, int n_digit,
103 int* decpt, int* sign, int* len, int format)
104 #else
105 char* _sfcvt(vp,buf,size,n_digit,decpt,sign,len,format)
106 Void_t* vp; /* pointer to value to convert */
107 char* buf; /* conversion goes here */
108 size_t size; /* size of buf */
109 int n_digit; /* number of digits wanted */
110 int* decpt; /* to return decimal point */
111 int* sign; /* to return sign */
112 int* len; /* return string length */
113 int format; /* conversion format */
114 #endif
115 {
116 reg char *sp;
117 reg long n, v;
118 reg char *ep, *b, *endsp, *t;
119 int x;
120 _ast_flt_unsigned_max_t m;
121
122 static char lx[] = "0123456789abcdef";
123 static char ux[] = "0123456789ABCDEF";
124
125 *sign = *decpt = 0;
126
127 #if !_ast_fltmax_double
128 if(format&SFFMT_LDOUBLE)
129 { Sfdouble_t f = *(Sfdouble_t*)vp;
130
131 if(isnanl(f))
132 {
133 #if _lib_signbit
134 if (signbit(f))
135 #else
136 if (f < 0)
137 #endif
138 *sign = 1;
139 return SF_NAN;
140 }
141 #if _lib_isinf
142 if (n = isinf(f))
143 {
144 #if _lib_signbit
145 if (signbit(f))
146 #else
147 if (n < 0 || f < 0)
148 #endif
149 *sign = 1;
150 return SF_INF;
151 }
152 #endif
153 # if _c99_in_the_wild
154 # if _lib_signbit
155 if (signbit(f))
156 # else
157 # if _lib_copysignl
158 if (copysignl(1.0, f) < 0.0)
159 # else
160 # if _lib_copysign
161 if (copysign(1.0, (double)f) < 0.0)
162 # else
163 if (f < 0.0)
164 # endif
165 # endif
166 # endif
167 { f = -f;
168 *sign = 1;
169 }
170 # if _lib_fpclassify
171 switch (fpclassify(f))
172 {
173 case FP_INFINITE:
174 return SF_INF;
175 case FP_NAN:
176 return SF_NAN;
177 case FP_ZERO:
178 return SF_ZERO;
179 }
180 # endif
181 # else
182 # if _lib_signbit
183 if (signbit(f))
184 # else
185 if (f < 0.0 || f == 0.0 && neg0ld(f))
186 # endif
187 { f = -f;
188 *sign = 1;
189 }
190 # endif
191 if(f < LDBL_MIN)
192 return SF_ZERO;
193 if(f > LDBL_MAX)
194 return SF_INF;
195
196 if(format & SFFMT_AFORMAT)
197 { Sfdouble_t g;
198 b = sp = buf;
199 ep = (format & SFFMT_UPPER) ? ux : lx;
200 if(n_digit <= 0 || n_digit >= (size - 9))
201 n_digit = size - 9;
202 endsp = sp + n_digit + 1;
203
204 g = frexpl(f, &x);
205 *decpt = x;
206 f = ldexpl(g, 8 * sizeof(m) - 3);
207
208 for (;;)
209 { m = f;
210 x = 8 * sizeof(m);
211 while ((x -= 4) >= 0)
212 { *sp++ = ep[(m >> x) & 0xf];
213 if (sp >= endsp)
214 goto around;
215 }
216 f -= m;
217 f = ldexpl(f, 8 * sizeof(m));
218 }
219 }
220
221 n = 0;
222 if(f >= (Sfdouble_t)CVT_LDBL_MAXINT)
223 { /* scale to a small enough number to fit an int */
224 v = SF_MAXEXP10-1;
225 do
226 { if(f < _Sfpos10[v])
227 v -= 1;
228 else
229 {
230 f *= _Sfneg10[v];
231 if((n += (1<<v)) >= SF_IDIGITS)
232 return SF_INF;
233 }
234 } while(f >= (Sfdouble_t)CVT_LDBL_MAXINT);
235 }
236 else if(f > 0.0 && f < 0.1)
237 { /* scale to avoid excessive multiply by 10 below */
238 v = SF_MAXEXP10-1;
239 do
240 { if(f <= _Sfneg10[v])
241 { f *= _Sfpos10[v];
242 if((n += (1<<v)) >= SF_IDIGITS)
243 return SF_INF;
244 }
245 else if (--v < 0)
246 break;
247 } while(f < 0.1);
248 n = -n;
249 }
250 *decpt = (int)n;
251
252 b = sp = buf + SF_INTPART;
253 if((v = (CVT_LDBL_INT)f) != 0)
254 { /* translate the integer part */
255 f -= (Sfdouble_t)v;
256
257 sfucvt(v,sp,n,ep,CVT_LDBL_INT,unsigned CVT_LDBL_INT);
258
259 n = b-sp;
260 if((*decpt += (int)n) >= SF_IDIGITS)
261 return SF_INF;
262 b = sp;
263 sp = buf + SF_INTPART;
264 }
265 else n = 0;
266
267 /* remaining number of digits to compute; add 1 for later rounding */
268 n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
269 if(n_digit > 0)
270 { if(n_digit > LDBL_DIG)
271 n_digit = LDBL_DIG;
272 n += n_digit;
273 }
274
275 if((ep = (sp+n)) > (endsp = buf+(size-2)))
276 ep = endsp;
277 if(sp > ep)
278 sp = ep;
279 else
280 {
281 if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.)
282 { Sfdouble_t d;
283 while((long)(d = f*10.) == 0)
284 { f = d;
285 *decpt -= 1;
286 }
287 }
288
289 while(sp < ep)
290 { /* generate fractional digits */
291 if(f <= 0.)
292 { /* fill with 0's */
293 do { *sp++ = '0'; } while(sp < ep);
294 goto done;
295 }
296 else if((n = (long)(f *= 10.)) < 10)
297 { *sp++ = '0' + n;
298 f -= n;
299 }
300 else /* n == 10 */
301 { do { *sp++ = '9'; } while(sp < ep);
302 }
303 }
304 }
305 } else
306 #endif
307 { double f = *(double*)vp;
308
309 if(isnan(f))
310 {
311 #if _lib_signbit
312 if (signbit(f))
313 #else
314 if (f < 0)
315 #endif
316 *sign = 1;
317 return SF_NAN;
318 }
319 #if _lib_isinf
320 if (n = isinf(f))
321 {
322 #if _lib_signbit
323 if (signbit(f))
324 #else
325 if (n < 0 || f < 0)
326 #endif
327 *sign = 1;
328 return SF_INF;
329 }
330 #endif
331 #if _c99_in_the_wild
332 # if _lib_signbit
333 if (signbit(f))
334 # else
335 # if _lib_copysign
336 if (copysign(1.0, f) < 0.0)
337 # else
338 if (f < 0.0)
339 # endif
340 # endif
341 { f = -f;
342 *sign = 1;
343 }
344 # if _lib_fpclassify
345 switch (fpclassify(f))
346 {
347 case FP_INFINITE:
348 return SF_INF;
349 case FP_NAN:
350 return SF_NAN;
351 case FP_ZERO:
352 return SF_ZERO;
353 }
354 # endif
355 #else
356 # if _lib_signbit
357 if (signbit(f))
358 # else
359 if (f < 0.0 || f == 0.0 && neg0d(f))
360 # endif
361 { f = -f;
362 *sign = 1;
363 }
364 #endif
365 if(f < DBL_MIN)
366 return SF_ZERO;
367 if(f > DBL_MAX)
368 return SF_INF;
369
370 if(format & SFFMT_AFORMAT)
371 { double g;
372 b = sp = buf;
373 ep = (format & SFFMT_UPPER) ? ux : lx;
374 if(n_digit <= 0 || n_digit >= (size - 9))
375 n_digit = size - 9;
376 endsp = sp + n_digit + 1;
377
378 g = frexp(f, &x);
379 *decpt = x;
380 f = ldexp(g, 8 * sizeof(m) - 3);
381
382 for (;;)
383 { m = f;
384 x = 8 * sizeof(m);
385 while ((x -= 4) >= 0)
386 { *sp++ = ep[(m >> x) & 0xf];
387 if (sp >= endsp)
388 goto around;
389 }
390 f -= m;
391 f = ldexp(f, 8 * sizeof(m));
392 }
393 }
394 n = 0;
395 if(f >= (double)CVT_DBL_MAXINT)
396 { /* scale to a small enough number to fit an int */
397 v = SF_MAXEXP10-1;
398 do
399 { if(f < _Sfpos10[v])
400 v -= 1;
401 else
402 { f *= _Sfneg10[v];
403 if((n += (1<<v)) >= SF_IDIGITS)
404 return SF_INF;
405 }
406 } while(f >= (double)CVT_DBL_MAXINT);
407 }
408 else if(f > 0.0 && f < 1e-8)
409 { /* scale to avoid excessive multiply by 10 below */
410 v = SF_MAXEXP10-1;
411 do
412 { if(f <= _Sfneg10[v])
413 { f *= _Sfpos10[v];
414 if((n += (1<<v)) >= SF_IDIGITS)
415 return SF_INF;
416 }
417 else if(--v < 0)
418 break;
419 } while(f < 0.1);
420 n = -n;
421 }
422 *decpt = (int)n;
423
424 b = sp = buf + SF_INTPART;
425 if((v = (CVT_DBL_INT)f) != 0)
426 { /* translate the integer part */
427 f -= (double)v;
428
429 sfucvt(v,sp,n,ep,CVT_DBL_INT,unsigned CVT_DBL_INT);
430
431 n = b-sp;
432 if((*decpt += (int)n) >= SF_IDIGITS)
433 return SF_INF;
434 b = sp;
435 sp = buf + SF_INTPART;
436 }
437 else n = 0;
438
439 /* remaining number of digits to compute; add 1 for later rounding */
440 n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
441 if(n_digit > 0)
442 { if(n_digit > DBL_DIG)
443 n_digit = DBL_DIG;
444 n += n_digit;
445 }
446
447 if((ep = (sp+n)) > (endsp = buf+(size-2)))
448 ep = endsp;
449 if(sp > ep)
450 sp = ep;
451 else
452 {
453 if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.)
454 { reg double d;
455 while((long)(d = f*10.) == 0)
456 { f = d;
457 *decpt -= 1;
458 }
459 }
460
461 while(sp < ep)
462 { /* generate fractional digits */
463 if(f <= 0.)
464 { /* fill with 0's */
465 do { *sp++ = '0'; } while(sp < ep);
466 goto done;
467 }
468 else if((n = (long)(f *= 10.)) < 10)
469 { *sp++ = (char)('0' + n);
470 f -= n;
471 }
472 else /* n == 10 */
473 { do { *sp++ = '9'; } while(sp < ep);
474 break;
475 }
476 }
477 }
478 }
479
480 if(ep <= b)
481 ep = b+1;
482 else if(ep < endsp)
483 { /* round the last digit */
484 *--sp += 5;
485 while(*sp > '9')
486 { *sp = '0';
487 if(sp > b)
488 *--sp += 1;
489 else
490 { /* next power of 10 */
491 *sp = '1';
492 *decpt += 1;
493 if(!(format&SFFMT_EFORMAT))
494 { /* add one more 0 for %f precision */
495 ep[-1] = '0';
496 ep += 1;
497 }
498 }
499 }
500 }
501
502 done:
503 *--ep = '\0';
504 if(len)
505 *len = ep-b;
506 return b;
507 around:
508 if (((m >> x) & 0xf) >= 8)
509 { t = sp - 1;
510 for (;;)
511 { if (--t <= b)
512 { (*decpt)++;
513 break;
514 }
515 switch (*t)
516 {
517 case 'f':
518 case 'F':
519 *t = '0';
520 continue;
521 case '9':
522 *t = ep[10];
523 break;
524 default:
525 (*t)++;
526 break;
527 }
528 break;
529 }
530 }
531 ep = sp + 1;
532 goto done;
533 }
534