source: trunk/gcc/libjava/java/lang/strtod.c

Last change on this file was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 14.9 KB
Line 
1/*
2FUNCTION
3 <<strtod>>, <<strtodf>>---string to double or float
4
5INDEX
6 strtod
7INDEX
8 _strtod_r
9INDEX
10 strtodf
11
12ANSI_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
20TRAD_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
35DESCRIPTION
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
60RETURNS
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
68Supporting 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 dmg@research.att.com or research!dmg
98 */
99
100#include <string.h>
101#include <float.h>
102#include <errno.h>
103#include "mprec.h"
104
105double
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 }
147break2:
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 }
209dig_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 }
706retfree:
707 Bfree (ptr, bb);
708 Bfree (ptr, bd);
709 Bfree (ptr, bs);
710 Bfree (ptr, bd0);
711 Bfree (ptr, delta);
712ret:
713 if (se)
714 *se = (char *) s;
715 if (digits == 0)
716 ptr->_errno = EINVAL;
717 return sign ? -rv.d : rv.d;
718}
719
Note: See TracBrowser for help on using the repository browser.