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 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 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 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