| 1 | /*
|
|---|
| 2 | FUNCTION
|
|---|
| 3 | <<strtod>>, <<strtodf>>---string to double or float
|
|---|
| 4 |
|
|---|
| 5 | INDEX
|
|---|
| 6 | strtod
|
|---|
| 7 | INDEX
|
|---|
| 8 | _strtod_r
|
|---|
| 9 | INDEX
|
|---|
| 10 | strtodf
|
|---|
| 11 |
|
|---|
| 12 | ANSI_SYNOPSIS
|
|---|
| 13 | #include <stdlib.h>
|
|---|
| 14 | double strtod(const char *<[str]>, char **<[tail]>);
|
|---|
| 15 | float strtodf(const char *<[str]>, char **<[tail]>);
|
|---|
| 16 |
|
|---|
| 17 | double _strtod_r(void *<[reent]>,
|
|---|
| 18 | const char *<[str]>, char **<[tail]>);
|
|---|
| 19 |
|
|---|
| 20 | TRAD_SYNOPSIS
|
|---|
| 21 | #include <stdlib.h>
|
|---|
| 22 | double strtod(<[str]>,<[tail]>)
|
|---|
| 23 | char *<[str]>;
|
|---|
| 24 | char **<[tail]>;
|
|---|
| 25 |
|
|---|
| 26 | float strtodf(<[str]>,<[tail]>)
|
|---|
| 27 | char *<[str]>;
|
|---|
| 28 | char **<[tail]>;
|
|---|
| 29 |
|
|---|
| 30 | double _strtod_r(<[reent]>,<[str]>,<[tail]>)
|
|---|
| 31 | char *<[reent]>;
|
|---|
| 32 | char *<[str]>;
|
|---|
| 33 | char **<[tail]>;
|
|---|
| 34 |
|
|---|
| 35 | DESCRIPTION
|
|---|
| 36 | The function <<strtod>> parses the character string <[str]>,
|
|---|
| 37 | producing a substring which can be converted to a double
|
|---|
| 38 | value. The substring converted is the longest initial
|
|---|
| 39 | subsequence of <[str]>, beginning with the first
|
|---|
| 40 | non-whitespace character, that has the format:
|
|---|
| 41 | .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
|
|---|
| 42 | The substring contains no characters if <[str]> is empty, consists
|
|---|
| 43 | entirely of whitespace, or if the first non-whitespace
|
|---|
| 44 | character is something other than <<+>>, <<->>, <<.>>, or a
|
|---|
| 45 | digit. If the substring is empty, no conversion is done, and
|
|---|
| 46 | the value of <[str]> is stored in <<*<[tail]>>>. Otherwise,
|
|---|
| 47 | the substring is converted, and a pointer to the final string
|
|---|
| 48 | (which will contain at least the terminating null character of
|
|---|
| 49 | <[str]>) is stored in <<*<[tail]>>>. If you want no
|
|---|
| 50 | assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
|
|---|
| 51 | <<strtodf>> is identical to <<strtod>> except for its return type.
|
|---|
| 52 |
|
|---|
| 53 | This implementation returns the nearest machine number to the
|
|---|
| 54 | input decimal string. Ties are broken by using the IEEE
|
|---|
| 55 | round-even rule.
|
|---|
| 56 |
|
|---|
| 57 | The alternate function <<_strtod_r>> is a reentrant version.
|
|---|
| 58 | The extra argument <[reent]> is a pointer to a reentrancy structure.
|
|---|
| 59 |
|
|---|
| 60 | RETURNS
|
|---|
| 61 | <<strtod>> returns the converted substring value, if any. If
|
|---|
| 62 | no conversion could be performed, 0 is returned. If the
|
|---|
| 63 | correct value is out of the range of representable values,
|
|---|
| 64 | plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
|
|---|
| 65 | stored in errno. If the correct value would cause underflow, 0
|
|---|
| 66 | is returned and <<ERANGE>> is stored in errno.
|
|---|
| 67 |
|
|---|
| 68 | Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
|---|
| 69 | <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
|---|
| 70 | */
|
|---|
| 71 |
|
|---|
| 72 | /****************************************************************
|
|---|
| 73 | *
|
|---|
| 74 | * The author of this software is David M. Gay.
|
|---|
| 75 | *
|
|---|
| 76 | * Copyright (c) 1991 by AT&T.
|
|---|
| 77 | *
|
|---|
| 78 | * Permission to use, copy, modify, and distribute this software for any
|
|---|
| 79 | * purpose without fee is hereby granted, provided that this entire notice
|
|---|
| 80 | * is included in all copies of any software which is or includes a copy
|
|---|
| 81 | * or modification of this software and in all copies of the supporting
|
|---|
| 82 | * documentation for such software.
|
|---|
| 83 | *
|
|---|
| 84 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
|---|
| 85 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
|
|---|
| 86 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
|---|
| 87 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
|---|
| 88 | *
|
|---|
| 89 | ***************************************************************/
|
|---|
| 90 |
|
|---|
| 91 | /* Please send bug reports to
|
|---|
| 92 | David M. Gay
|
|---|
| 93 | AT&T Bell Laboratories, Room 2C-463
|
|---|
| 94 | 600 Mountain Avenue
|
|---|
| 95 | Murray Hill, NJ 07974-2070
|
|---|
| 96 | U.S.A.
|
|---|
| 97 | [email protected] or research!dmg
|
|---|
| 98 | */
|
|---|
| 99 |
|
|---|
| 100 | #include <string.h>
|
|---|
| 101 | #include <float.h>
|
|---|
| 102 | #include <errno.h>
|
|---|
| 103 | #include "mprec.h"
|
|---|
| 104 |
|
|---|
| 105 | double
|
|---|
| 106 | _DEFUN (_strtod_r, (ptr, s00, se),
|
|---|
| 107 | struct _Jv_reent *ptr _AND
|
|---|
| 108 | _CONST char *s00 _AND
|
|---|
| 109 | char **se)
|
|---|
| 110 | {
|
|---|
| 111 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j,
|
|---|
| 112 | k, nd, nd0, nf, nz, nz0, sign;
|
|---|
| 113 | int digits = 0; /* Number of digits found in fraction part. */
|
|---|
| 114 | long e;
|
|---|
| 115 | _CONST char *s, *s0, *s1;
|
|---|
| 116 | double aadj, aadj1, adj;
|
|---|
| 117 | long L;
|
|---|
| 118 | unsigned long y, z;
|
|---|
| 119 | union double_union rv, rv0;
|
|---|
| 120 |
|
|---|
| 121 | _Jv_Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
|
|---|
| 122 | sign = nz0 = nz = 0;
|
|---|
| 123 | rv.d = 0.;
|
|---|
| 124 | for (s = s00;; s++)
|
|---|
| 125 | switch (*s)
|
|---|
| 126 | {
|
|---|
| 127 | case '-':
|
|---|
| 128 | sign = 1;
|
|---|
| 129 | /* no break */
|
|---|
| 130 | case '+':
|
|---|
| 131 | if (*++s)
|
|---|
| 132 | goto break2;
|
|---|
| 133 | /* no break */
|
|---|
| 134 | case 0:
|
|---|
| 135 | s = s00;
|
|---|
| 136 | goto ret;
|
|---|
| 137 | case '\t':
|
|---|
| 138 | case '\n':
|
|---|
| 139 | case '\v':
|
|---|
| 140 | case '\f':
|
|---|
| 141 | case '\r':
|
|---|
| 142 | case ' ':
|
|---|
| 143 | continue;
|
|---|
| 144 | default:
|
|---|
| 145 | goto break2;
|
|---|
| 146 | }
|
|---|
| 147 | break2:
|
|---|
| 148 | if (*s == '0')
|
|---|
| 149 | {
|
|---|
| 150 | digits++;
|
|---|
| 151 | nz0 = 1;
|
|---|
| 152 | while (*++s == '0')
|
|---|
| 153 | digits++;
|
|---|
| 154 | if (!*s)
|
|---|
| 155 | goto ret;
|
|---|
| 156 | }
|
|---|
| 157 | s0 = s;
|
|---|
| 158 | y = z = 0;
|
|---|
| 159 | for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
|
|---|
| 160 | {
|
|---|
| 161 | digits++;
|
|---|
| 162 | if (nd < 9)
|
|---|
| 163 | y = 10 * y + c - '0';
|
|---|
| 164 | else if (nd < 16)
|
|---|
| 165 | z = 10 * z + c - '0';
|
|---|
| 166 | }
|
|---|
| 167 | nd0 = nd;
|
|---|
| 168 | if (c == '.')
|
|---|
| 169 | {
|
|---|
| 170 | c = *++s;
|
|---|
| 171 | if (!nd)
|
|---|
| 172 | {
|
|---|
| 173 | for (; c == '0'; c = *++s)
|
|---|
| 174 | {
|
|---|
| 175 | digits++;
|
|---|
| 176 | nz++;
|
|---|
| 177 | }
|
|---|
| 178 | if (c > '0' && c <= '9')
|
|---|
| 179 | {
|
|---|
| 180 | digits++;
|
|---|
| 181 | s0 = s;
|
|---|
| 182 | nf += nz;
|
|---|
| 183 | nz = 0;
|
|---|
| 184 | goto have_dig;
|
|---|
| 185 | }
|
|---|
| 186 | goto dig_done;
|
|---|
| 187 | }
|
|---|
| 188 | for (; c >= '0' && c <= '9'; c = *++s)
|
|---|
| 189 | {
|
|---|
| 190 | digits++;
|
|---|
| 191 | have_dig:
|
|---|
| 192 | nz++;
|
|---|
| 193 | if (c -= '0')
|
|---|
| 194 | {
|
|---|
| 195 | nf += nz;
|
|---|
| 196 | for (i = 1; i < nz; i++)
|
|---|
| 197 | if (nd++ < 9)
|
|---|
| 198 | y *= 10;
|
|---|
| 199 | else if (nd <= DBL_DIG + 1)
|
|---|
| 200 | z *= 10;
|
|---|
| 201 | if (nd++ < 9)
|
|---|
| 202 | y = 10 * y + c;
|
|---|
| 203 | else if (nd <= DBL_DIG + 1)
|
|---|
| 204 | z = 10 * z + c;
|
|---|
| 205 | nz = 0;
|
|---|
| 206 | }
|
|---|
| 207 | }
|
|---|
| 208 | }
|
|---|
| 209 | dig_done:
|
|---|
| 210 | e = 0;
|
|---|
| 211 | if (c == 'e' || c == 'E')
|
|---|
| 212 | {
|
|---|
| 213 | if (!nd && !nz && !nz0)
|
|---|
| 214 | {
|
|---|
| 215 | s = s00;
|
|---|
| 216 | goto ret;
|
|---|
| 217 | }
|
|---|
| 218 | s00 = s;
|
|---|
| 219 | esign = 0;
|
|---|
| 220 | switch (c = *++s)
|
|---|
| 221 | {
|
|---|
| 222 | case '-':
|
|---|
| 223 | esign = 1;
|
|---|
| 224 | case '+':
|
|---|
| 225 | c = *++s;
|
|---|
| 226 | }
|
|---|
| 227 | if (c >= '0' && c <= '9')
|
|---|
| 228 | {
|
|---|
| 229 | while (c == '0')
|
|---|
| 230 | c = *++s;
|
|---|
| 231 | if (c > '0' && c <= '9')
|
|---|
| 232 | {
|
|---|
| 233 | e = c - '0';
|
|---|
| 234 | s1 = s;
|
|---|
| 235 | while ((c = *++s) >= '0' && c <= '9')
|
|---|
| 236 | e = 10 * e + c - '0';
|
|---|
| 237 | if (s - s1 > 8)
|
|---|
| 238 | /* Avoid confusion from exponents
|
|---|
| 239 | * so large that e might overflow.
|
|---|
| 240 | */
|
|---|
| 241 | e = 9999999L;
|
|---|
| 242 | if (esign)
|
|---|
| 243 | e = -e;
|
|---|
| 244 | }
|
|---|
| 245 | }
|
|---|
| 246 | else
|
|---|
| 247 | {
|
|---|
| 248 | /* No exponent after an 'E' : that's an error. */
|
|---|
| 249 | ptr->_errno = EINVAL;
|
|---|
| 250 | e = 0;
|
|---|
| 251 | s = s00;
|
|---|
| 252 | goto ret;
|
|---|
| 253 | }
|
|---|
| 254 | }
|
|---|
| 255 | if (!nd)
|
|---|
| 256 | {
|
|---|
| 257 | if (!nz && !nz0)
|
|---|
| 258 | s = s00;
|
|---|
| 259 | goto ret;
|
|---|
| 260 | }
|
|---|
| 261 | e1 = e -= nf;
|
|---|
| 262 |
|
|---|
| 263 | /* Now we have nd0 digits, starting at s0, followed by a
|
|---|
| 264 | * decimal point, followed by nd-nd0 digits. The number we're
|
|---|
| 265 | * after is the integer represented by those digits times
|
|---|
| 266 | * 10**e */
|
|---|
| 267 |
|
|---|
| 268 | if (!nd0)
|
|---|
| 269 | nd0 = nd;
|
|---|
| 270 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
|
|---|
| 271 | rv.d = y;
|
|---|
| 272 | if (k > 9)
|
|---|
| 273 | rv.d = tens[k - 9] * rv.d + z;
|
|---|
| 274 | bd0 = 0;
|
|---|
| 275 | if (nd <= DBL_DIG
|
|---|
| 276 | #ifndef RND_PRODQUOT
|
|---|
| 277 | && FLT_ROUNDS == 1
|
|---|
| 278 | #endif
|
|---|
| 279 | )
|
|---|
| 280 | {
|
|---|
| 281 | if (!e)
|
|---|
| 282 | goto ret;
|
|---|
| 283 | if (e > 0)
|
|---|
| 284 | {
|
|---|
| 285 | if (e <= Ten_pmax)
|
|---|
| 286 | {
|
|---|
| 287 | #ifdef VAX
|
|---|
| 288 | goto vax_ovfl_check;
|
|---|
| 289 | #else
|
|---|
| 290 | /* rv.d = */ rounded_product (rv.d, tens[e]);
|
|---|
| 291 | goto ret;
|
|---|
| 292 | #endif
|
|---|
| 293 | }
|
|---|
| 294 | i = DBL_DIG - nd;
|
|---|
| 295 | if (e <= Ten_pmax + i)
|
|---|
| 296 | {
|
|---|
| 297 | /* A fancier test would sometimes let us do
|
|---|
| 298 | * this for larger i values.
|
|---|
| 299 | */
|
|---|
| 300 | e -= i;
|
|---|
| 301 | rv.d *= tens[i];
|
|---|
| 302 | #ifdef VAX
|
|---|
| 303 | /* VAX exponent range is so narrow we must
|
|---|
| 304 | * worry about overflow here...
|
|---|
| 305 | */
|
|---|
| 306 | vax_ovfl_check:
|
|---|
| 307 | word0 (rv) -= P * Exp_msk1;
|
|---|
| 308 | /* rv.d = */ rounded_product (rv.d, tens[e]);
|
|---|
| 309 | if ((word0 (rv) & Exp_mask)
|
|---|
| 310 | > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
|
|---|
| 311 | goto ovfl;
|
|---|
| 312 | word0 (rv) += P * Exp_msk1;
|
|---|
| 313 | #else
|
|---|
| 314 | /* rv.d = */ rounded_product (rv.d, tens[e]);
|
|---|
| 315 | #endif
|
|---|
| 316 | goto ret;
|
|---|
| 317 | }
|
|---|
| 318 | }
|
|---|
| 319 | #ifndef Inaccurate_Divide
|
|---|
| 320 | else if (e >= -Ten_pmax)
|
|---|
| 321 | {
|
|---|
| 322 | /* rv.d = */ rounded_quotient (rv.d, tens[-e]);
|
|---|
| 323 | goto ret;
|
|---|
| 324 | }
|
|---|
| 325 | #endif
|
|---|
| 326 | }
|
|---|
| 327 | e1 += nd - k;
|
|---|
| 328 |
|
|---|
| 329 | /* Get starting approximation = rv.d * 10**e1 */
|
|---|
| 330 |
|
|---|
| 331 | if (e1 > 0)
|
|---|
| 332 | {
|
|---|
| 333 | if ((i = e1 & 15))
|
|---|
| 334 | rv.d *= tens[i];
|
|---|
| 335 |
|
|---|
| 336 | if (e1 &= ~15)
|
|---|
| 337 | {
|
|---|
| 338 | if (e1 > DBL_MAX_10_EXP)
|
|---|
| 339 | {
|
|---|
| 340 | ovfl:
|
|---|
| 341 | ptr->_errno = ERANGE;
|
|---|
| 342 |
|
|---|
| 343 | /* Force result to IEEE infinity. */
|
|---|
| 344 | word0 (rv) = Exp_mask;
|
|---|
| 345 | word1 (rv) = 0;
|
|---|
| 346 |
|
|---|
| 347 | if (bd0)
|
|---|
| 348 | goto retfree;
|
|---|
| 349 | goto ret;
|
|---|
| 350 | }
|
|---|
| 351 | if (e1 >>= 4)
|
|---|
| 352 | {
|
|---|
| 353 | for (j = 0; e1 > 1; j++, e1 >>= 1)
|
|---|
| 354 | if (e1 & 1)
|
|---|
| 355 | rv.d *= bigtens[j];
|
|---|
| 356 | /* The last multiplication could overflow. */
|
|---|
| 357 | word0 (rv) -= P * Exp_msk1;
|
|---|
| 358 | rv.d *= bigtens[j];
|
|---|
| 359 | if ((z = word0 (rv) & Exp_mask)
|
|---|
| 360 | > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
|
|---|
| 361 | goto ovfl;
|
|---|
| 362 | if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
|
|---|
| 363 | {
|
|---|
| 364 | /* set to largest number */
|
|---|
| 365 | /* (Can't trust DBL_MAX) */
|
|---|
| 366 | word0 (rv) = Big0;
|
|---|
| 367 | #ifndef _DOUBLE_IS_32BITS
|
|---|
| 368 | word1 (rv) = Big1;
|
|---|
| 369 | #endif
|
|---|
| 370 | }
|
|---|
| 371 | else
|
|---|
| 372 | word0 (rv) += P * Exp_msk1;
|
|---|
| 373 | }
|
|---|
| 374 |
|
|---|
| 375 | }
|
|---|
| 376 | }
|
|---|
| 377 | else if (e1 < 0)
|
|---|
| 378 | {
|
|---|
| 379 | e1 = -e1;
|
|---|
| 380 | if ((i = e1 & 15))
|
|---|
| 381 | rv.d /= tens[i];
|
|---|
| 382 | if (e1 &= ~15)
|
|---|
| 383 | {
|
|---|
| 384 | e1 >>= 4;
|
|---|
| 385 | if (e1 >= 1 << n_bigtens)
|
|---|
| 386 | goto undfl;
|
|---|
| 387 | for (j = 0; e1 > 1; j++, e1 >>= 1)
|
|---|
| 388 | if (e1 & 1)
|
|---|
| 389 | rv.d *= tinytens[j];
|
|---|
| 390 | /* The last multiplication could underflow. */
|
|---|
| 391 | rv0.d = rv.d;
|
|---|
| 392 | rv.d *= tinytens[j];
|
|---|
| 393 | if (!rv.d)
|
|---|
| 394 | {
|
|---|
| 395 | rv.d = 2. * rv0.d;
|
|---|
| 396 | rv.d *= tinytens[j];
|
|---|
| 397 | if (!rv.d)
|
|---|
| 398 | {
|
|---|
| 399 | undfl:
|
|---|
| 400 | rv.d = 0.;
|
|---|
| 401 | ptr->_errno = ERANGE;
|
|---|
| 402 | if (bd0)
|
|---|
| 403 | goto retfree;
|
|---|
| 404 | goto ret;
|
|---|
| 405 | }
|
|---|
| 406 | #ifndef _DOUBLE_IS_32BITS
|
|---|
| 407 | word0 (rv) = Tiny0;
|
|---|
| 408 | word1 (rv) = Tiny1;
|
|---|
| 409 | #else
|
|---|
| 410 | word0 (rv) = Tiny1;
|
|---|
| 411 | #endif
|
|---|
| 412 | /* The refinement below will clean
|
|---|
| 413 | * this approximation up.
|
|---|
| 414 | */
|
|---|
| 415 | }
|
|---|
| 416 | }
|
|---|
| 417 | }
|
|---|
| 418 |
|
|---|
| 419 | /* Now the hard part -- adjusting rv to the correct value.*/
|
|---|
| 420 |
|
|---|
| 421 | /* Put digits into bd: true value = bd * 10^e */
|
|---|
| 422 |
|
|---|
| 423 | bd0 = s2b (ptr, s0, nd0, nd, y);
|
|---|
| 424 |
|
|---|
| 425 | for (;;)
|
|---|
| 426 | {
|
|---|
| 427 | bd = Balloc (ptr, bd0->_k);
|
|---|
| 428 | Bcopy (bd, bd0);
|
|---|
| 429 | bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */
|
|---|
| 430 | bs = i2b (ptr, 1);
|
|---|
| 431 |
|
|---|
| 432 | if (e >= 0)
|
|---|
| 433 | {
|
|---|
| 434 | bb2 = bb5 = 0;
|
|---|
| 435 | bd2 = bd5 = e;
|
|---|
| 436 | }
|
|---|
| 437 | else
|
|---|
| 438 | {
|
|---|
| 439 | bb2 = bb5 = -e;
|
|---|
| 440 | bd2 = bd5 = 0;
|
|---|
| 441 | }
|
|---|
| 442 | if (bbe >= 0)
|
|---|
| 443 | bb2 += bbe;
|
|---|
| 444 | else
|
|---|
| 445 | bd2 -= bbe;
|
|---|
| 446 | bs2 = bb2;
|
|---|
| 447 | #ifdef Sudden_Underflow
|
|---|
| 448 | #ifdef IBM
|
|---|
| 449 | j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
|
|---|
| 450 | #else
|
|---|
| 451 | j = P + 1 - bbbits;
|
|---|
| 452 | #endif
|
|---|
| 453 | #else
|
|---|
| 454 | i = bbe + bbbits - 1; /* logb(rv.d) */
|
|---|
| 455 | if (i < Emin) /* denormal */
|
|---|
| 456 | j = bbe + (P - Emin);
|
|---|
| 457 | else
|
|---|
| 458 | j = P + 1 - bbbits;
|
|---|
| 459 | #endif
|
|---|
| 460 | bb2 += j;
|
|---|
| 461 | bd2 += j;
|
|---|
| 462 | i = bb2 < bd2 ? bb2 : bd2;
|
|---|
| 463 | if (i > bs2)
|
|---|
| 464 | i = bs2;
|
|---|
| 465 | if (i > 0)
|
|---|
| 466 | {
|
|---|
| 467 | bb2 -= i;
|
|---|
| 468 | bd2 -= i;
|
|---|
| 469 | bs2 -= i;
|
|---|
| 470 | }
|
|---|
| 471 | if (bb5 > 0)
|
|---|
| 472 | {
|
|---|
| 473 | bs = pow5mult (ptr, bs, bb5);
|
|---|
| 474 | bb1 = mult (ptr, bs, bb);
|
|---|
| 475 | Bfree (ptr, bb);
|
|---|
| 476 | bb = bb1;
|
|---|
| 477 | }
|
|---|
| 478 | if (bb2 > 0)
|
|---|
| 479 | bb = lshift (ptr, bb, bb2);
|
|---|
| 480 | if (bd5 > 0)
|
|---|
| 481 | bd = pow5mult (ptr, bd, bd5);
|
|---|
| 482 | if (bd2 > 0)
|
|---|
| 483 | bd = lshift (ptr, bd, bd2);
|
|---|
| 484 | if (bs2 > 0)
|
|---|
| 485 | bs = lshift (ptr, bs, bs2);
|
|---|
| 486 | delta = diff (ptr, bb, bd);
|
|---|
| 487 | dsign = delta->_sign;
|
|---|
| 488 | delta->_sign = 0;
|
|---|
| 489 | i = cmp (delta, bs);
|
|---|
| 490 | if (i < 0)
|
|---|
| 491 | {
|
|---|
| 492 | /* Error is less than half an ulp -- check for
|
|---|
| 493 | * special case of mantissa a power of two.
|
|---|
| 494 | */
|
|---|
| 495 | if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
|
|---|
| 496 | break;
|
|---|
| 497 | delta = lshift (ptr, delta, Log2P);
|
|---|
| 498 | if (cmp (delta, bs) > 0)
|
|---|
| 499 | goto drop_down;
|
|---|
| 500 | break;
|
|---|
| 501 | }
|
|---|
| 502 | if (i == 0)
|
|---|
| 503 | {
|
|---|
| 504 | /* exactly half-way between */
|
|---|
| 505 | if (dsign)
|
|---|
| 506 | {
|
|---|
| 507 | if ((word0 (rv) & Bndry_mask1) == Bndry_mask1
|
|---|
| 508 | && word1 (rv) == 0xffffffff)
|
|---|
| 509 | {
|
|---|
| 510 | /*boundary case -- increment exponent*/
|
|---|
| 511 | word0 (rv) = (word0 (rv) & Exp_mask)
|
|---|
| 512 | + Exp_msk1
|
|---|
| 513 | #ifdef IBM
|
|---|
| 514 | | Exp_msk1 >> 4
|
|---|
| 515 | #endif
|
|---|
| 516 | ;
|
|---|
| 517 | #ifndef _DOUBLE_IS_32BITS
|
|---|
| 518 | word1 (rv) = 0;
|
|---|
| 519 | #endif
|
|---|
| 520 | break;
|
|---|
| 521 | }
|
|---|
| 522 | }
|
|---|
| 523 | else if (!(word0 (rv) & Bndry_mask) && !word1 (rv))
|
|---|
| 524 | {
|
|---|
| 525 | drop_down:
|
|---|
| 526 | /* boundary case -- decrement exponent */
|
|---|
| 527 | #ifdef Sudden_Underflow
|
|---|
| 528 | L = word0 (rv) & Exp_mask;
|
|---|
| 529 | #ifdef IBM
|
|---|
| 530 | if (L < Exp_msk1)
|
|---|
| 531 | #else
|
|---|
| 532 | if (L <= Exp_msk1)
|
|---|
| 533 | #endif
|
|---|
| 534 | goto undfl;
|
|---|
| 535 | L -= Exp_msk1;
|
|---|
| 536 | #else
|
|---|
| 537 | L = (word0 (rv) & Exp_mask) - Exp_msk1;
|
|---|
| 538 | #endif
|
|---|
| 539 | word0 (rv) = L | Bndry_mask1;
|
|---|
| 540 | #ifndef _DOUBLE_IS_32BITS
|
|---|
| 541 | word1 (rv) = 0xffffffff;
|
|---|
| 542 | #endif
|
|---|
| 543 | #ifdef IBM
|
|---|
| 544 | goto cont;
|
|---|
| 545 | #else
|
|---|
| 546 | break;
|
|---|
| 547 | #endif
|
|---|
| 548 | }
|
|---|
| 549 | #ifndef ROUND_BIASED
|
|---|
| 550 | if (!(word1 (rv) & LSB))
|
|---|
| 551 | break;
|
|---|
| 552 | #endif
|
|---|
| 553 | if (dsign)
|
|---|
| 554 | rv.d += ulp (rv.d);
|
|---|
| 555 | #ifndef ROUND_BIASED
|
|---|
| 556 | else
|
|---|
| 557 | {
|
|---|
| 558 | rv.d -= ulp (rv.d);
|
|---|
| 559 | #ifndef Sudden_Underflow
|
|---|
| 560 | if (!rv.d)
|
|---|
| 561 | goto undfl;
|
|---|
| 562 | #endif
|
|---|
| 563 | }
|
|---|
| 564 | #endif
|
|---|
| 565 | break;
|
|---|
| 566 | }
|
|---|
| 567 | if ((aadj = ratio (delta, bs)) <= 2.)
|
|---|
| 568 | {
|
|---|
| 569 | if (dsign)
|
|---|
| 570 | aadj = aadj1 = 1.;
|
|---|
| 571 | else if (word1 (rv) || word0 (rv) & Bndry_mask)
|
|---|
| 572 | {
|
|---|
| 573 | #ifndef Sudden_Underflow
|
|---|
| 574 | if (word1 (rv) == Tiny1 && !word0 (rv))
|
|---|
| 575 | goto undfl;
|
|---|
| 576 | #endif
|
|---|
| 577 | aadj = 1.;
|
|---|
| 578 | aadj1 = -1.;
|
|---|
| 579 | }
|
|---|
| 580 | else
|
|---|
| 581 | {
|
|---|
| 582 | /* special case -- power of FLT_RADIX to be */
|
|---|
| 583 | /* rounded down... */
|
|---|
| 584 |
|
|---|
| 585 | if (aadj < 2. / FLT_RADIX)
|
|---|
| 586 | aadj = 1. / FLT_RADIX;
|
|---|
| 587 | else
|
|---|
| 588 | aadj *= 0.5;
|
|---|
| 589 | aadj1 = -aadj;
|
|---|
| 590 | }
|
|---|
| 591 | }
|
|---|
| 592 | else
|
|---|
| 593 | {
|
|---|
| 594 | aadj *= 0.5;
|
|---|
| 595 | aadj1 = dsign ? aadj : -aadj;
|
|---|
| 596 | #ifdef Check_FLT_ROUNDS
|
|---|
| 597 | switch (FLT_ROUNDS)
|
|---|
| 598 | {
|
|---|
| 599 | case 2: /* towards +infinity */
|
|---|
| 600 | aadj1 -= 0.5;
|
|---|
| 601 | break;
|
|---|
| 602 | case 0: /* towards 0 */
|
|---|
| 603 | case 3: /* towards -infinity */
|
|---|
| 604 | aadj1 += 0.5;
|
|---|
| 605 | }
|
|---|
| 606 | #else
|
|---|
| 607 | if (FLT_ROUNDS == 0)
|
|---|
| 608 | aadj1 += 0.5;
|
|---|
| 609 | #endif
|
|---|
| 610 | }
|
|---|
| 611 | y = word0 (rv) & Exp_mask;
|
|---|
| 612 |
|
|---|
| 613 | /* Check for overflow */
|
|---|
| 614 |
|
|---|
| 615 | if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
|
|---|
| 616 | {
|
|---|
| 617 | rv0.d = rv.d;
|
|---|
| 618 | word0 (rv) -= P * Exp_msk1;
|
|---|
| 619 | adj = aadj1 * ulp (rv.d);
|
|---|
| 620 | rv.d += adj;
|
|---|
| 621 | if ((word0 (rv) & Exp_mask) >=
|
|---|
| 622 | Exp_msk1 * (DBL_MAX_EXP + Bias - P))
|
|---|
| 623 | {
|
|---|
| 624 | if (word0 (rv0) == Big0 && word1 (rv0) == Big1)
|
|---|
| 625 | goto ovfl;
|
|---|
| 626 | #ifdef _DOUBLE_IS_32BITS
|
|---|
| 627 | word0 (rv) = Big1;
|
|---|
| 628 | #else
|
|---|
| 629 | word0 (rv) = Big0;
|
|---|
| 630 | word1 (rv) = Big1;
|
|---|
| 631 | #endif
|
|---|
| 632 | goto cont;
|
|---|
| 633 | }
|
|---|
| 634 | else
|
|---|
| 635 | word0 (rv) += P * Exp_msk1;
|
|---|
| 636 | }
|
|---|
| 637 | else
|
|---|
| 638 | {
|
|---|
| 639 | #ifdef Sudden_Underflow
|
|---|
| 640 | if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
|
|---|
| 641 | {
|
|---|
| 642 | rv0.d = rv.d;
|
|---|
| 643 | word0 (rv) += P * Exp_msk1;
|
|---|
| 644 | adj = aadj1 * ulp (rv.d);
|
|---|
| 645 | rv.d += adj;
|
|---|
| 646 | #ifdef IBM
|
|---|
| 647 | if ((word0 (rv) & Exp_mask) < P * Exp_msk1)
|
|---|
| 648 | #else
|
|---|
| 649 | if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
|
|---|
| 650 | #endif
|
|---|
| 651 | {
|
|---|
| 652 | if (word0 (rv0) == Tiny0
|
|---|
| 653 | && word1 (rv0) == Tiny1)
|
|---|
| 654 | goto undfl;
|
|---|
| 655 | word0 (rv) = Tiny0;
|
|---|
| 656 | word1 (rv) = Tiny1;
|
|---|
| 657 | goto cont;
|
|---|
| 658 | }
|
|---|
| 659 | else
|
|---|
| 660 | word0 (rv) -= P * Exp_msk1;
|
|---|
| 661 | }
|
|---|
| 662 | else
|
|---|
| 663 | {
|
|---|
| 664 | adj = aadj1 * ulp (rv.d);
|
|---|
| 665 | rv.d += adj;
|
|---|
| 666 | }
|
|---|
| 667 | #else
|
|---|
| 668 | /* Compute adj so that the IEEE rounding rules will
|
|---|
| 669 | * correctly round rv.d + adj in some half-way cases.
|
|---|
| 670 | * If rv.d * ulp(rv.d) is denormalized (i.e.,
|
|---|
| 671 | * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
|
|---|
| 672 | * trouble from bits lost to denormalization;
|
|---|
| 673 | * example: 1.2e-307 .
|
|---|
| 674 | */
|
|---|
| 675 | if (y <= (P - 1) * Exp_msk1 && aadj >= 1.)
|
|---|
| 676 | {
|
|---|
| 677 | aadj1 = (double) (int) (aadj + 0.5);
|
|---|
| 678 | if (!dsign)
|
|---|
| 679 | aadj1 = -aadj1;
|
|---|
| 680 | }
|
|---|
| 681 | adj = aadj1 * ulp (rv.d);
|
|---|
| 682 | rv.d += adj;
|
|---|
| 683 | #endif
|
|---|
| 684 | }
|
|---|
| 685 | z = word0 (rv) & Exp_mask;
|
|---|
| 686 | if (y == z)
|
|---|
| 687 | {
|
|---|
| 688 | /* Can we stop now? */
|
|---|
| 689 | L = aadj;
|
|---|
| 690 | aadj -= L;
|
|---|
| 691 | /* The tolerances below are conservative. */
|
|---|
| 692 | if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
|
|---|
| 693 | {
|
|---|
| 694 | if (aadj < .4999999 || aadj > .5000001)
|
|---|
| 695 | break;
|
|---|
| 696 | }
|
|---|
| 697 | else if (aadj < .4999999 / FLT_RADIX)
|
|---|
| 698 | break;
|
|---|
| 699 | }
|
|---|
| 700 | cont:
|
|---|
| 701 | Bfree (ptr, bb);
|
|---|
| 702 | Bfree (ptr, bd);
|
|---|
| 703 | Bfree (ptr, bs);
|
|---|
| 704 | Bfree (ptr, delta);
|
|---|
| 705 | }
|
|---|
| 706 | retfree:
|
|---|
| 707 | Bfree (ptr, bb);
|
|---|
| 708 | Bfree (ptr, bd);
|
|---|
| 709 | Bfree (ptr, bs);
|
|---|
| 710 | Bfree (ptr, bd0);
|
|---|
| 711 | Bfree (ptr, delta);
|
|---|
| 712 | ret:
|
|---|
| 713 | if (se)
|
|---|
| 714 | *se = (char *) s;
|
|---|
| 715 | if (digits == 0)
|
|---|
| 716 | ptr->_errno = EINVAL;
|
|---|
| 717 | return sign ? -rv.d : rv.d;
|
|---|
| 718 | }
|
|---|
| 719 |
|
|---|