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