1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 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 61 static int neg0ld(Sfdouble_t f) 62 { 63 Sfdouble_t z = -0.0; 64 return !memcmp(&f, &z, sizeof(f)); 65 } 66 #endif 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 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