|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * the Systems Programming Group of the University of Utah Computer
7: * Science Department.
8: *
9: * Redistribution and use in source and binary forms are permitted
10: * provided that: (1) source distributions retain this entire copyright
11: * notice and comment, and (2) distributions including binaries display
12: * the following acknowledgement: ``This product includes software
13: * developed by the University of California, Berkeley and its contributors''
14: * in the documentation or other materials provided with the distribution
15: * and in all advertising materials mentioning features or use of this
16: * software. Neither the name of the University nor the names of its
17: * contributors may be used to endorse or promote products derived
18: * from this software without specific prior written permission.
19: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
21: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22: */
23:
24: #if defined(LIBC_SCCS) && !defined(lint)
25: static char sccsid[] = "@(#)atof.c 5.1 (Berkeley) 5/12/90";
26: #endif /* LIBC_SCCS and not lint */
27:
28: #include <ctype.h>
29:
30: double _twoemax =
31: #ifdef IEEE
32: 9007199254740992.; /*2^53*/
33: #else
34: 72057594037927936.; /*2^56*/
35: #endif
36:
37: #ifdef hp300
38: /* attempt to be as exact as possible */
39: struct {
40: long d_high;
41: long d_low;
42: } _exp5[] = {
43: { 0x40140000, 0x00000000 }, /* 5 */
44: { 0x40390000, 0x00000000 }, /* 25 */
45: { 0x40838800, 0x00000000 }, /* 625 */
46: { 0x4117d784, 0x00000000 }, /* 390625 */
47: { 0x4241c379, 0x37e08000 }, /* 152587890625 */
48: { 0x4493b8b5, 0xb5056e17 }, /* 2.3283064365387e+022 */
49: { 0x49384f03, 0xe93ff9f6 }, /* 5.42101086242753e+044 */
50: { 0x52827748, 0xf9301d33 }, /* 2.93873587705572e+089 */
51: { 0x65154fdd, 0x7f73bf3f } /* 8.63616855509445e+178 */
52: };
53: #else
54: double _exp5[] = {
55: 5.,
56: 25.,
57: 625.,
58: 390625.,
59: 152587890625.,
60: 23283064365386962890625.,
61: #ifdef IEEE
62: 5.4210108624275231e+044,
63: 2.9387358770557196e+089,
64: 8.6361685550944492e+178,
65: #endif
66: };
67: #endif
68:
69: double
70: atof(p)
71: register char *p;
72: {
73: extern double ldexp();
74: register c, exp = 0, eexp = 0;
75: double fl = 0, flexp = 1.0;
76: int bexp, neg = 1, negexp = 1;
77:
78: while((c = *p++) == ' ');
79: if (c == '-') neg = -1; else if (c == '+'); else --p;
80:
81: while ((c = *p++), isdigit(c))
82: if (fl < _twoemax) fl = 10*fl + (c-'0'); else exp++;
83: if (c == '.')
84: while ((c = *p++), isdigit(c))
85: if (fl < _twoemax)
86: {
87: fl = 10*fl + (c-'0');
88: exp--;
89: }
90: if ((c == 'E') || (c == 'e'))
91: {
92: if ((c= *p++) == '+'); else if (c=='-') negexp = -1; else --p;
93: while ((c = *p++), isdigit(c)) eexp = 10*eexp + (c-'0');
94: if (negexp < 0) eexp = -eexp; exp += eexp;
95: }
96: bexp = exp;
97: if (exp < 0) exp = -exp;
98:
99: for (c = 0; c < sizeof(_exp5)/sizeof(_exp5[0]); c++)
100: {
101: #ifdef hp300
102: if (exp & 01) flexp *= *(double *)&_exp5[c];
103: #else
104: if (exp & 01) flexp *= _exp5[c];
105: #endif
106: exp >>= 1; if (exp == 0) break;
107: }
108:
109: if (bexp < 0) fl /= flexp; else fl *= flexp;
110: fl = ldexp(fl, bexp);
111: if (neg < 0) return(-fl); else return(fl);
112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.