Contiki 2.6
|
00001 /* 00002 FUNCTON 00003 <<strtod>>, <<strtof>>---string to double or float 00004 00005 INDEX 00006 strtod 00007 INDEX 00008 _strtod_r 00009 INDEX 00010 strtof 00011 00012 ANSI_SYNOPSIS 00013 #include <stdlib.h> 00014 double strtod(const char *<[str]>, char **<[tail]>); 00015 float strtof(const char *<[str]>, char **<[tail]>); 00016 00017 double _strtod_r(void *<[reent]>, 00018 const char *<[str]>, char **<[tail]>); 00019 00020 TRAD_SYNOPSIS 00021 #include <stdlib.h> 00022 double strtod(<[str]>,<[tail]>) 00023 char *<[str]>; 00024 char **<[tail]>; 00025 00026 float strtof(<[str]>,<[tail]>) 00027 char *<[str]>; 00028 char **<[tail]>; 00029 00030 double _strtod_r(<[reent]>,<[str]>,<[tail]>) 00031 char *<[reent]>; 00032 char *<[str]>; 00033 char **<[tail]>; 00034 00035 DESCRIPTION 00036 The function <<strtod>> parses the character string <[str]>, 00037 producing a substring which can be converted to a double 00038 value. The substring converted is the longest initial 00039 subsequence of <[str]>, beginning with the first 00040 non-whitespace character, that has the format: 00041 .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] 00042 The substring contains no characters if <[str]> is empty, consists 00043 entirely of whitespace, or if the first non-whitespace 00044 character is something other than <<+>>, <<->>, <<.>>, or a 00045 digit. If the substring is empty, no conversion is done, and 00046 the value of <[str]> is stored in <<*<[tail]>>>. Otherwise, 00047 the substring is converted, and a pointer to the final string 00048 (which will contain at least the terminating null character of 00049 <[str]>) is stored in <<*<[tail]>>>. If you want no 00050 assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>. 00051 <<strtof>> is identical to <<strtod>> except for its return type. 00052 00053 This implementation returns the nearest machine number to the 00054 input decimal string. Ties are broken by using the IEEE 00055 round-even rule. 00056 00057 The alternate function <<_strtod_r>> is a reentrant version. 00058 The extra argument <[reent]> is a pointer to a reentrancy structure. 00059 00060 RETURNS 00061 <<strtod>> returns the converted substring value, if any. If 00062 no conversion could be performed, 0 is returned. If the 00063 correct value is out of the range of representable values, 00064 plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is 00065 stored in errno. If the correct value would cause underflow, 0 00066 is returned and <<ERANGE>> is stored in errno. 00067 00068 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, 00069 <<lseek>>, <<read>>, <<sbrk>>, <<write>>. 00070 */ 00071 00072 /**************************************************************** 00073 * 00074 * The author of this software is David M. Gay. 00075 * 00076 * Copyright (c) 1991 by AT&T. 00077 * 00078 * Permission to use, copy, modify, and distribute this software for any 00079 * purpose without fee is hereby granted, provided that this entire notice 00080 * is included in all copies of any software which is or includes a copy 00081 * or modification of this software and in all copies of the supporting 00082 * documentation for such software. 00083 * 00084 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 00085 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY 00086 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 00087 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 00088 * 00089 ***************************************************************/ 00090 00091 /* Please send bug reports to 00092 David M. Gay 00093 AT&T Bell Laboratories, Room 2C-463 00094 600 Mountain Avenue 00095 Murray Hill, NJ 07974-2070 00096 U.S.A. 00097 dmg@research.att.com or research!dmg 00098 */ 00099 00100 00101 /* Scanf and printf call both the small_mprec.c file if small_scanf 00102 * has not been specfied optimizations concerning small_mprec.c and 00103 * call of balloc will be performed anyway for scanf. 00104 */ 00105 00106 #ifdef _SMALL_PRINTF 00107 #ifndef SMALL_SCANF 00108 #define SMALL_SCANF 00109 #endif 00110 #endif 00111 00112 00113 #include <_ansi.h> 00114 #include <reent.h> 00115 #include <string.h> 00116 #include "small_mprec.h" 00117 00118 double 00119 _DEFUN (_strtod_r, (ptr, s00, se), 00120 struct _reent *ptr _AND 00121 _CONST char *s00 _AND 00122 char **se) 00123 { 00124 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j, 00125 k, nd, nd0, nf, nz, nz0, sign; 00126 long e; 00127 _CONST char *s, *s0, *s1; 00128 double aadj, aadj1, adj; 00129 long L; 00130 unsigned long z; 00131 __ULong y; 00132 union double_union rv, rv0; 00133 00134 _Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 00135 00136 #ifdef SMALL_SCANF 00137 00138 /* 00139 * For the SMALL_SCANF implementation for floating points numbers : 00140 * - To avoid the call of allocator we defined a buffer for each variable : instead of taking the adress 00141 * provided by Balloc variables are initialized to the beginning of the array. 00142 * - For some variables many buffers have been declared, in fact for each call of small_lshift we used a 00143 * buffer that has not been used at the moment 00144 * - This buffers are used in the call of function declared in small_mprec.h 00145 * To have more informations look at small_mprec.c 00146 */ 00147 00148 00149 00150 #define BUF_SIZE 32 00151 #define BUF_LSHIFT_SIZE 40 00152 00153 _Bigint tab_bb[BUF_LSHIFT_SIZE],tab_bb1[BUF_SIZE],tab_bd[BUF_SIZE],tab_bd0[BUF_SIZE],tab_bs[BUF_LSHIFT_SIZE], tab_delta[BUF_LSHIFT_SIZE]; 00154 _Bigint tab_bblshift[BUF_LSHIFT_SIZE],tab_bslshift[BUF_LSHIFT_SIZE], tab_deltalshift[BUF_LSHIFT_SIZE],tab_bdlshift[BUF_LSHIFT_SIZE]; 00155 #endif 00156 00157 sign = nz0 = nz = 0; 00158 rv.d = 0.; 00159 for (s = s00;; s++) 00160 switch (*s) 00161 { 00162 case '-': 00163 sign = 1; 00164 /* no break */ 00165 case '+': 00166 if (*++s) 00167 goto break2; 00168 /* no break */ 00169 case 0: 00170 s = s00; 00171 goto ret; 00172 case '\t': 00173 case '\n': 00174 case '\v': 00175 case '\f': 00176 case '\r': 00177 case ' ': 00178 continue; 00179 default: 00180 goto break2; 00181 } 00182 break2: 00183 if (*s == '0') 00184 { 00185 nz0 = 1; 00186 while (*++s == '0'); 00187 if (!*s) 00188 goto ret; 00189 } 00190 s0 = s; 00191 y = z = 0; 00192 for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) 00193 if (nd < 9) 00194 y = 10 * y + c - '0'; 00195 else if (nd < 16) 00196 z = 10 * z + c - '0'; 00197 nd0 = nd; 00198 if (c == '.') 00199 { 00200 c = *++s; 00201 if (!nd) 00202 { 00203 for (; c == '0'; c = *++s) 00204 nz++; 00205 if (c > '0' && c <= '9') 00206 { 00207 s0 = s; 00208 nf += nz; 00209 nz = 0; 00210 goto have_dig; 00211 } 00212 goto dig_done; 00213 } 00214 for (; c >= '0' && c <= '9'; c = *++s) 00215 { 00216 have_dig: 00217 nz++; 00218 if (c -= '0') 00219 { 00220 nf += nz; 00221 for (i = 1; i < nz; i++) 00222 if (nd++ < 9) 00223 y *= 10; 00224 else if (nd <= DBL_DIG + 1) 00225 z *= 10; 00226 if (nd++ < 9) 00227 y = 10 * y + c; 00228 else if (nd <= DBL_DIG + 1) 00229 z = 10 * z + c; 00230 nz = 0; 00231 } 00232 } 00233 } 00234 dig_done: 00235 e = 0; 00236 if (c == 'e' || c == 'E') 00237 { 00238 if (!nd && !nz && !nz0) 00239 { 00240 s = s00; 00241 goto ret; 00242 } 00243 s00 = s; 00244 esign = 0; 00245 switch (c = *++s) 00246 { 00247 case '-': 00248 esign = 1; 00249 case '+': 00250 c = *++s; 00251 } 00252 if (c >= '0' && c <= '9') 00253 { 00254 while (c == '0') 00255 c = *++s; 00256 if (c > '0' && c <= '9') 00257 { 00258 e = c - '0'; 00259 s1 = s; 00260 while ((c = *++s) >= '0' && c <= '9') 00261 e = 10 * e + c - '0'; 00262 if (s - s1 > 8) 00263 /* Avoid confusion from exponents 00264 * so large that e might overflow. 00265 */ 00266 e = 9999999L; 00267 if (esign) 00268 e = -e; 00269 } 00270 else 00271 e = 0; 00272 } 00273 else 00274 s = s00; 00275 } 00276 if (!nd) 00277 { 00278 if (!nz && !nz0) 00279 s = s00; 00280 goto ret; 00281 } 00282 e1 = e -= nf; 00283 00284 /* Now we have nd0 digits, starting at s0, followed by a 00285 * decimal point, followed by nd-nd0 digits. The number we're 00286 * after is the integer represented by those digits times 00287 * 10**e */ 00288 00289 if (!nd0) 00290 nd0 = nd; 00291 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 00292 rv.d = y; 00293 if (k > 9) 00294 #ifndef SMALL_SCANF 00295 rv.d = tens[k - 9] * rv.d + z; 00296 #else 00297 rv.d = small_tens[k - 9] * rv.d + z; 00298 #endif 00299 bd0 = 0; 00300 if (nd <= DBL_DIG 00301 #ifndef RND_PRODQUOT 00302 && FLT_ROUNDS == 1 00303 #endif 00304 ) 00305 { 00306 if (!e) 00307 goto ret; 00308 if (e > 0) 00309 { 00310 if (e <= Ten_pmax) 00311 { 00312 #ifdef VAX 00313 goto vax_ovfl_check; 00314 #else 00315 #ifndef SMALL_SCANF 00316 /* rv.d = */ rounded_product (rv.d, tens[e]); 00317 #else 00318 rounded_product (rv.d, small_tens[e]); 00319 #endif 00320 goto ret; 00321 #endif 00322 } 00323 i = DBL_DIG - nd; 00324 if (e <= Ten_pmax + i) 00325 { 00326 /* A fancier test would sometimes let us do 00327 * this for larger i values. 00328 */ 00329 e -= i; 00330 #ifndef SMALL_SCANF 00331 rv.d *= tens[i]; 00332 #else 00333 rv.d *= small_tens[i]; 00334 #endif 00335 #ifdef VAX 00336 /* VAX exponent range is so narrow we must 00337 * worry about overflow here... 00338 */ 00339 vax_ovfl_check: 00340 word0 (rv) -= P * Exp_msk1; 00341 #ifndef SMALL_SCANF 00342 /* rv.d = */ rounded_product (rv.d, tens[e]); 00343 #else 00344 /* rv.d = */ rounded_product (rv.d, small_tens[e]); 00345 #endif 00346 if ((word0 (rv) & Exp_mask) 00347 > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) 00348 goto ovfl; 00349 word0 (rv) += P * Exp_msk1; 00350 #else 00351 #ifndef SMALL_SCANF 00352 /* rv.d = */ rounded_product (rv.d, tens[e]); 00353 #else 00354 /* rv.d = */ rounded_product (rv.d, small_tens[e]); 00355 #endif 00356 #endif 00357 goto ret; 00358 } 00359 } 00360 #ifndef Inaccurate_Divide 00361 else if (e >= -Ten_pmax) 00362 { 00363 #ifndef SMALL_SCANF 00364 /* rv.d = */ rounded_quotient (rv.d, tens[-e]); 00365 #else 00366 /* rv.d = */ rounded_quotient (rv.d, small_tens[-e]); 00367 #endif 00368 goto ret; 00369 } 00370 #endif 00371 } 00372 e1 += nd - k; 00373 00374 /* Get starting approximation = rv.d * 10**e1 */ 00375 00376 if (e1 > 0) 00377 { 00378 if ((i = e1 & 15) != 0) 00379 #ifndef SMALL_SCANF 00380 rv.d *= tens[i]; 00381 #else 00382 rv.d *= small_tens[i]; 00383 #endif 00384 if (e1 &= ~15) 00385 { 00386 if (e1 > DBL_MAX_10_EXP) 00387 { 00388 ovfl: 00389 ptr->_errno = ERANGE; 00390 #ifdef _HAVE_STDC 00391 rv.d = HUGE_VAL; 00392 #else 00393 /* Can't trust HUGE_VAL */ 00394 #ifdef IEEE_Arith 00395 word0 (rv) = Exp_mask; 00396 #ifndef _DOUBLE_IS_32BITS 00397 word1 (rv) = 0; 00398 #endif 00399 #else 00400 word0 (rv) = Big0; 00401 #ifndef _DOUBLE_IS_32BITS 00402 word1 (rv) = Big1; 00403 #endif 00404 #endif 00405 #endif 00406 if (bd0) 00407 goto retfree; 00408 goto ret; 00409 } 00410 if (e1 >>= 4) 00411 { 00412 for (j = 0; e1 > 1; j++, e1 >>= 1) 00413 if (e1 & 1) 00414 #ifndef SMALL_SCANF 00415 rv.d *= bigtens[j]; 00416 #else 00417 rv.d *= small_bigtens[j]; 00418 #endif 00419 00420 /* The last multiplication could overflow. */ 00421 word0 (rv) -= P * Exp_msk1; 00422 #ifndef SMALL_SCANF 00423 rv.d *= bigtens[j]; 00424 #else 00425 rv.d *= small_bigtens[j]; 00426 #endif 00427 00428 if ((z = word0 (rv) & Exp_mask) 00429 > Exp_msk1 * (DBL_MAX_EXP + Bias - P)) 00430 goto ovfl; 00431 if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) 00432 { 00433 /* set to largest number */ 00434 /* (Can't trust DBL_MAX) */ 00435 word0 (rv) = Big0; 00436 #ifndef _DOUBLE_IS_32BITS 00437 word1 (rv) = Big1; 00438 #endif 00439 } 00440 else 00441 word0 (rv) += P * Exp_msk1; 00442 } 00443 00444 } 00445 } 00446 else if (e1 < 0) 00447 { 00448 e1 = -e1; 00449 if ((i = e1 & 15) != 0) 00450 #ifndef SMALL_SCANF 00451 rv.d /= tens[i]; 00452 #else 00453 rv.d /= small_tens[i]; 00454 #endif 00455 if (e1 &= ~15) 00456 { 00457 e1 >>= 4; 00458 if (e1 >= 1 << n_bigtens) 00459 goto undfl; 00460 for (j = 0; e1 > 1; j++, e1 >>= 1) 00461 if (e1 & 1) 00462 #ifndef SMALL_SCANF 00463 rv.d *= tinytens[j]; 00464 /* The last multiplication could underflow. */ 00465 rv0.d = rv.d; 00466 rv.d *=tinytens[j]; 00467 #else 00468 rv.d *= small_tinytens[j]; 00469 /* The last multiplication could underflow. */ 00470 rv0.d = rv.d; 00471 rv.d *= small_tinytens[j]; 00472 #endif 00473 if (!rv.d) 00474 { 00475 rv.d = 2. * rv0.d; 00476 #ifndef SMALL_SCANF 00477 rv.d *= tinytens[j]; 00478 #else 00479 rv.d *= small_tinytens[j]; 00480 #endif 00481 if (!rv.d) 00482 { 00483 undfl: 00484 rv.d = 0.; 00485 ptr->_errno = ERANGE; 00486 if (bd0) 00487 goto retfree; 00488 goto ret; 00489 } 00490 #ifndef _DOUBLE_IS_32BITS 00491 word0 (rv) = Tiny0; 00492 word1 (rv) = Tiny1; 00493 #else 00494 word0 (rv) = Tiny1; 00495 #endif 00496 /* The refinement below will clean 00497 * this approximation up. 00498 */ 00499 } 00500 } 00501 } 00502 00503 /* Now the hard part -- adjusting rv to the correct value.*/ 00504 00505 /* Put digits into bd: true value = bd * 10^e */ 00506 #ifndef SMALL_SCANF 00507 bd0 = s2b (ptr, s0, nd0, nd, y); 00508 #else 00509 bd0 = small_s2b(ptr,s0, nd0, nd, y, &tab_bd0[0]); 00510 #endif 00511 00512 for (;;) 00513 { 00514 #ifndef SMALL_SCANF 00515 bd = Balloc (ptr, bd0->_k); 00516 #else 00517 bd = &tab_bd[0]; 00518 bd->_k = bd0->_k; 00519 bd->_maxwds = 1 << (bd0->_k); 00520 bd->_sign = bd->_wds =0; 00521 00522 #endif 00523 Bcopy (bd, bd0); 00524 #ifndef SMALL_SCANF 00525 bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */ 00526 bs = i2b (ptr, 1); 00527 #else 00528 bb = small_d2b (ptr, rv.d, &bbe, &bbbits, &tab_bb[0]); /* rv.d = bb * 2^bbe */ 00529 bs = small_i2b (ptr, 1, &tab_bs[0]); 00530 #endif 00531 if (e >= 0) 00532 { 00533 bb2 = bb5 = 0; 00534 bd2 = bd5 = e; 00535 } 00536 else 00537 { 00538 bb2 = bb5 = -e; 00539 bd2 = bd5 = 0; 00540 } 00541 if (bbe >= 0) 00542 bb2 += bbe; 00543 else 00544 bd2 -= bbe; 00545 bs2 = bb2; 00546 #ifdef Sudden_Underflow 00547 #ifdef IBM 00548 j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3); 00549 #else 00550 j = P + 1 - bbbits; 00551 #endif 00552 #else 00553 i = bbe + bbbits - 1; /* logb(rv.d) */ 00554 if (i < Emin) /* denormal */ 00555 j = bbe + (P - Emin); 00556 else 00557 j = P + 1 - bbbits; 00558 #endif 00559 bb2 += j; 00560 bd2 += j; 00561 i = bb2 < bd2 ? bb2 : bd2; 00562 if (i > bs2) 00563 i = bs2; 00564 if (i > 0) 00565 { 00566 bb2 -= i; 00567 bd2 -= i; 00568 bs2 -= i; 00569 } 00570 if (bb5 > 0) 00571 { 00572 #ifndef SMALL_SCANF 00573 bs = pow5mult (ptr, bs, bb5); 00574 bb1 = mult (ptr, bs, bb); 00575 Bfree (ptr, bb); 00576 bb = bb1; 00577 #else 00578 if (bs == &tab_bs[0]){ 00579 bs = small_pow5mult (ptr, bs, bb5,&tab_bslshift[0]); 00580 } 00581 else{ 00582 bs = small_pow5mult (ptr, bs, bb5,&tab_bs[0]); 00583 } 00584 bb1 = small_mult (ptr, bs, bb,&tab_bb1[0]); 00585 bb = bb1; 00586 #endif 00587 00588 } 00589 00590 #ifndef SMALL_SCANF 00591 if (bb2 > 0) 00592 bb = lshift (ptr, bb, bb2); 00593 if (bd5 > 0) 00594 bd = pow5mult (ptr, bd, bd5); 00595 if (bd2 > 0) 00596 bd = lshift (ptr, bd, bd2); 00597 if (bs2 > 0) 00598 bs = lshift (ptr, bs, bs2); 00599 delta = diff (ptr, bb, bd); 00600 dsign = delta->_sign; 00601 delta->_sign = 0; 00602 i = cmp (delta, bs); 00603 #else 00604 if (bb2 > 0){ 00605 if (bb == &tab_bb[0] ){ 00606 bb = small_lshift (ptr, bb, bb2,&tab_bblshift[0]); 00607 } 00608 else { 00609 bb = small_lshift (ptr, bb, bb2,&tab_bblshift[0]); 00610 } 00611 } 00612 if (bd5 > 0){ 00613 if (bd == &tab_bd[0]){ 00614 bd = small_pow5mult (ptr, bd, bd5, &tab_bdlshift[0]); 00615 } 00616 else{ 00617 bd = small_pow5mult (ptr, bd, bd5, &tab_bd[0]); 00618 } 00619 } 00620 if (bd2 > 0){ 00621 if (bd == &tab_bd[0] ){ 00622 bd = small_lshift (ptr, bb, bd2,&tab_bdlshift[0]); 00623 } 00624 else { 00625 bd = small_lshift (ptr, bd, bd2,&tab_bd[0]); 00626 } 00627 } 00628 if (bs2 > 0){ 00629 if ( bs == &tab_bs[0] ){ 00630 bs = small_lshift (ptr, bs, bs2,&tab_bslshift[0]); 00631 } 00632 else{ 00633 bs = small_lshift (ptr, bs, bs2,&tab_bs[0]); 00634 } 00635 } 00636 00637 delta = small_diff (ptr, bb, bd,&tab_delta[0]); 00638 dsign = delta->_sign; 00639 delta->_sign = 0; 00640 i = small_cmp (delta, bs); 00641 00642 #endif 00643 if (i < 0) 00644 { 00645 /* Error is less than half an ulp -- check for 00646 * special case of mantissa a power of two. 00647 */ 00648 if (dsign || word1 (rv) || word0 (rv) & Bndry_mask) 00649 break; 00650 00651 #ifndef SMALL_SCANF 00652 delta = lshift (ptr, delta, Log2P); 00653 if (cmp (delta, bs) > 0) 00654 goto drop_down; 00655 #else 00656 if (delta == &tab_delta[0]){ 00657 delta = small_lshift (ptr, delta, Log2P,&tab_deltalshift[0]); 00658 } 00659 else{ 00660 delta = small_lshift (ptr, delta, Log2P,&tab_delta[0]); 00661 } 00662 if (small_cmp (delta, bs) > 0) 00663 goto drop_down; 00664 #endif 00665 break; 00666 } 00667 if (i == 0) 00668 { 00669 /* exactly half-way between */ 00670 if (dsign) 00671 { 00672 if ((word0 (rv) & Bndry_mask1) == Bndry_mask1 00673 && word1 (rv) == 0xffffffff) 00674 { 00675 /*boundary case -- increment exponent*/ 00676 word0 (rv) = (word0 (rv) & Exp_mask) 00677 + Exp_msk1 00678 #ifdef IBM 00679 | Exp_msk1 >> 4 00680 #endif 00681 ; 00682 #ifndef _DOUBLE_IS_32BITS 00683 word1 (rv) = 0; 00684 #endif 00685 break; 00686 } 00687 } 00688 else if (!(word0 (rv) & Bndry_mask) && !word1 (rv)) 00689 { 00690 drop_down: 00691 /* boundary case -- decrement exponent */ 00692 #ifdef Sudden_Underflow 00693 L = word0 (rv) & Exp_mask; 00694 #ifdef IBM 00695 if (L < Exp_msk1) 00696 #else 00697 if (L <= Exp_msk1) 00698 #endif 00699 goto undfl; 00700 L -= Exp_msk1; 00701 #else 00702 L = (word0 (rv) & Exp_mask) - Exp_msk1; 00703 #endif 00704 word0 (rv) = L | Bndry_mask1; 00705 #ifndef _DOUBLE_IS_32BITS 00706 word1 (rv) = 0xffffffff; 00707 #endif 00708 #ifdef IBM 00709 goto cont; 00710 #else 00711 break; 00712 #endif 00713 } 00714 #ifndef ROUND_BIASED 00715 if (!(word1 (rv) & LSB)) 00716 break; 00717 #endif 00718 if (dsign) 00719 #ifndef SMALL_SCANF 00720 rv.d += ulp (rv.d); 00721 #else 00722 rv.d += small_ulp (rv.d); 00723 #endif 00724 #ifndef ROUND_BIASED 00725 else 00726 { 00727 #ifndef SMALL_SCANF 00728 rv.d -= ulp (rv.d); 00729 #else 00730 rv.d -= small_ulp (rv.d); 00731 #endif 00732 #ifndef Sudden_Underflow 00733 if (!rv.d) 00734 goto undfl; 00735 #endif 00736 } 00737 #endif 00738 break; 00739 } 00740 00741 #ifndef SMALL_SCANF 00742 if ((aadj = ratio (delta, bs)) <= 2.) 00743 { 00744 #else 00745 if ((aadj = small_ratio (delta, bs)) <= 2.) 00746 { 00747 #endif 00748 if (dsign) 00749 aadj = aadj1 = 1.; 00750 else if (word1 (rv) || word0 (rv) & Bndry_mask) 00751 { 00752 #ifndef Sudden_Underflow 00753 if (word1 (rv) == Tiny1 && !word0 (rv)) 00754 goto undfl; 00755 #endif 00756 aadj = 1.; 00757 aadj1 = -1.; 00758 } 00759 else 00760 { 00761 /* special case -- power of FLT_RADIX to be */ 00762 /* rounded down... */ 00763 00764 if (aadj < 2. / FLT_RADIX) 00765 aadj = 1. / FLT_RADIX; 00766 else 00767 aadj *= 0.5; 00768 aadj1 = -aadj; 00769 } 00770 } 00771 else 00772 { 00773 aadj *= 0.5; 00774 aadj1 = dsign ? aadj : -aadj; 00775 #ifdef Check_FLT_ROUNDS 00776 switch (FLT_ROUNDS) 00777 { 00778 case 2: /* towards +infinity */ 00779 aadj1 -= 0.5; 00780 break; 00781 case 0: /* towards 0 */ 00782 case 3: /* towards -infinity */ 00783 aadj1 += 0.5; 00784 } 00785 #else 00786 if (FLT_ROUNDS == 0) 00787 aadj1 += 0.5; 00788 #endif 00789 } 00790 y = word0 (rv) & Exp_mask; 00791 00792 /* Check for overflow */ 00793 00794 if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) 00795 { 00796 rv0.d = rv.d; 00797 word0 (rv) -= P * Exp_msk1; 00798 #ifndef SMALL_SCANF 00799 adj = aadj1 * ulp (rv.d); 00800 #else 00801 adj = aadj1 * small_ulp (rv.d); 00802 #endif 00803 rv.d += adj; 00804 if ((word0 (rv) & Exp_mask) >= 00805 Exp_msk1 * (DBL_MAX_EXP + Bias - P)) 00806 { 00807 if (word0 (rv0) == Big0 && word1 (rv0) == Big1) 00808 goto ovfl; 00809 #ifdef _DOUBLE_IS_32BITS 00810 word0 (rv) = Big1; 00811 #else 00812 word0 (rv) = Big0; 00813 word1 (rv) = Big1; 00814 #endif 00815 goto cont; 00816 } 00817 else 00818 word0 (rv) += P * Exp_msk1; 00819 } 00820 else 00821 { 00822 #ifdef Sudden_Underflow 00823 if ((word0 (rv) & Exp_mask) <= P * Exp_msk1) 00824 { 00825 rv0.d = rv.d; 00826 word0 (rv) += P * Exp_msk1; 00827 #ifndef SMALL_SCANF 00828 adj = aadj1 * ulp (rv.d); 00829 #else 00830 adj = aadj1 * small_ulp (rv.d); 00831 #endif 00832 rv.d += adj; 00833 #ifdef IBM 00834 if ((word0 (rv) & Exp_mask) < P * Exp_msk1) 00835 #else 00836 if ((word0 (rv) & Exp_mask) <= P * Exp_msk1) 00837 #endif 00838 { 00839 if (word0 (rv0) == Tiny0 00840 && word1 (rv0) == Tiny1) 00841 goto undfl; 00842 word0 (rv) = Tiny0; 00843 word1 (rv) = Tiny1; 00844 goto cont; 00845 } 00846 else 00847 word0 (rv) -= P * Exp_msk1; 00848 } 00849 else 00850 { 00851 #ifndef SMALL_SCANF 00852 adj = aadj1 * ulp (rv.d); 00853 #else 00854 adj = aadj1 * small_ulp (rv.d); 00855 #endif 00856 rv.d += adj; 00857 } 00858 #else 00859 /* Compute adj so that the IEEE rounding rules will 00860 * correctly round rv.d + adj in some half-way cases. 00861 * If rv.d * ulp(rv.d) is denormalized (i.e., 00862 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid 00863 * trouble from bits lost to denormalization; 00864 * example: 1.2e-307 . 00865 */ 00866 if (y <= (P - 1) * Exp_msk1 && aadj >= 1.) 00867 { 00868 aadj1 = (double) (int) (aadj + 0.5); 00869 if (!dsign) 00870 aadj1 = -aadj1; 00871 } 00872 #ifndef SMALL_SCANF 00873 adj = aadj1 * ulp (rv.d); 00874 #else 00875 adj = aadj1 * small_ulp (rv.d); 00876 rv.d += adj; 00877 #endif 00878 #endif 00879 } 00880 z = word0 (rv) & Exp_mask; 00881 if (y == z) 00882 { 00883 /* Can we stop now? */ 00884 L = aadj; 00885 aadj -= L; 00886 /* The tolerances below are conservative. */ 00887 if (dsign || word1 (rv) || word0 (rv) & Bndry_mask) 00888 { 00889 if (aadj < .4999999 || aadj > .5000001) 00890 break; 00891 } 00892 else if (aadj < .4999999 / FLT_RADIX) 00893 break; 00894 } 00895 cont: 00896 #ifndef SMALL_SCANF 00897 Bfree (ptr, bb); 00898 Bfree (ptr, bd); 00899 Bfree (ptr, bs); 00900 Bfree (ptr, delta); 00901 #else 00902 ; 00903 #endif 00904 } 00905 retfree: 00906 #ifndef SMALL_SCANF 00907 Bfree (ptr, bb); 00908 Bfree (ptr, bd); 00909 Bfree (ptr, bs); 00910 Bfree (ptr, bd0); 00911 Bfree (ptr, delta); 00912 #endif 00913 ret: 00914 if (se) 00915 *se = (char *) s; 00916 return sign ? -rv.d : rv.d; 00917 } 00918 00919 #ifndef NO_REENT 00920 00921 double 00922 _DEFUN (strtod, (s00, se), 00923 _CONST char *s00 _AND char **se) 00924 { 00925 return _strtod_r (_REENT, s00, se); 00926 } 00927 00928 float 00929 _DEFUN (strtof, (s00, se), 00930 _CONST char *s00 _AND 00931 char **se) 00932 { 00933 return (float)_strtod_r (_REENT, s00, se); 00934 } 00935 00936 #endif