Add tests, fixes for tests, reinstate and type-convert stuff marked "bitrot"
[ccom.git] / fp_atof.c
1 #ifndef pdp11
2 /*
3  * Copyright (c) 1987 Regents of the University of California.
4  * All rights reserved.  The Berkeley software License Agreement
5  * specifies the terms and conditions for redistribution.
6  */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)atof.c      2.2 (Berkeley) 1/22/87";
10 #endif
11
12 /*
13  *      C library - ascii to floating
14  */
15
16 #include <ctype.h>
17 #include "c1.h"
18
19 /*#define HUGE 1.701411733192644270e38*/
20 #define LOGHUGE 39
21
22 _DOUBLE fp_atof(p) register char *p; {
23         register int c;
24         _DOUBLE fl, flexp, exp5;
25         _DOUBLE big = { 0, 056200 << 16 }; /*= 72057594037927936.;*/  /*2^56*/
26         _DOUBLE ten = { 0, 041040 << 16 }; /*= 10.;*/
27         /*_DOUBLE fp_ldexp();*/
28         int nd;
29         register int eexp, exp, neg, negexp, bexp;
30
31         neg = 1;
32         while((c = *p++) == ' ')
33                 ;
34         if (c == '-')
35                 neg = -1;
36         else if (c=='+')
37                 ;
38         else
39                 --p;
40
41         exp = 0;
42         /*fl = 0;*/ fl.l = 0; fl.h = 0;
43         nd = 0;
44         while ((c = *p++), isdigit(c)) {
45                 if (fp_lt(fl, big))
46                         fl = fp_add(fp_mul(ten, fl), fp_int_to_double(c-'0'));
47                 else
48                         exp++;
49                 nd++;
50         }
51
52         if (c == '.') {
53                 while ((c = *p++), isdigit(c)) {
54                         if (fp_lt(fl, big)) {
55                                 fl = fp_add(fp_mul(ten, fl), fp_int_to_double(c-'0'));
56                                 exp--;
57                         }
58                 nd++;
59                 }
60         }
61
62         negexp = 1;
63         eexp = 0;
64         if ((c == 'E') || (c == 'e')) {
65                 if ((c= *p++) == '+')
66                         ;
67                 else if (c=='-')
68                         negexp = -1;
69                 else
70                         --p;
71
72                 while ((c = *p++), isdigit(c)) {
73                         eexp = 10*eexp+(c-'0');
74                 }
75                 if (negexp<0)
76                         eexp = -eexp;
77                 exp = exp + eexp;
78         }
79
80         negexp = 1;
81         if (exp<0) {
82                 negexp = -1;
83                 exp = -exp;
84         }
85
86
87         if((nd+exp*negexp) < -LOGHUGE){
88                 /*fl = 0;*/ fl.l = 0; fl.h = 0;
89                 exp = 0;
90         }
91         /*flexp = 1;*/ flexp.l = 0; flexp.h = 040200 << 16;
92         /*exp5 = 5;*/ exp5.l = 0; exp5.h = 040640 << 16;
93         bexp = exp;
94         for (;;) {
95                 if (exp&01)
96                         flexp = fp_mul(flexp, exp5);
97                 exp >>= 1;
98                 if (exp==0)
99                         break;
100                 exp5 = fp_mul(exp5, exp5);
101         }
102         if (negexp<0)
103                 fl = fp_div(fl, flexp);
104         else
105                 fl = fp_mul(fl, flexp);
106         fl = fp_ldexp(fl, negexp*bexp);
107         if (neg<0)
108                 fl = fp_neg(fl);
109         return(fl);
110 }
111 #endif