1*41806Sbostic /*- 2*41806Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*41806Sbostic * All rights reserved. 4*41806Sbostic * 5*41806Sbostic * This code is derived from software contributed to Berkeley by 6*41806Sbostic * the Systems Programming Group of the University of Utah Computer 7*41806Sbostic * Science Department. 8*41806Sbostic * 9*41806Sbostic * %sccs.include.redist.c% 10*41806Sbostic */ 11*41806Sbostic 12*41806Sbostic #if defined(LIBC_SCCS) && !defined(lint) 13*41806Sbostic static char sccsid[] = "@(#)atof.c 5.1 (Berkeley) 05/12/90"; 14*41806Sbostic #endif /* LIBC_SCCS and not lint */ 15*41806Sbostic 16*41806Sbostic #include <ctype.h> 17*41806Sbostic 18*41806Sbostic double _twoemax = 19*41806Sbostic #ifdef IEEE 20*41806Sbostic 9007199254740992.; /*2^53*/ 21*41806Sbostic #else 22*41806Sbostic 72057594037927936.; /*2^56*/ 23*41806Sbostic #endif 24*41806Sbostic 25*41806Sbostic #ifdef hp300 26*41806Sbostic /* attempt to be as exact as possible */ 27*41806Sbostic struct { 28*41806Sbostic long d_high; 29*41806Sbostic long d_low; 30*41806Sbostic } _exp5[] = { 31*41806Sbostic { 0x40140000, 0x00000000 }, /* 5 */ 32*41806Sbostic { 0x40390000, 0x00000000 }, /* 25 */ 33*41806Sbostic { 0x40838800, 0x00000000 }, /* 625 */ 34*41806Sbostic { 0x4117d784, 0x00000000 }, /* 390625 */ 35*41806Sbostic { 0x4241c379, 0x37e08000 }, /* 152587890625 */ 36*41806Sbostic { 0x4493b8b5, 0xb5056e17 }, /* 2.3283064365387e+022 */ 37*41806Sbostic { 0x49384f03, 0xe93ff9f6 }, /* 5.42101086242753e+044 */ 38*41806Sbostic { 0x52827748, 0xf9301d33 }, /* 2.93873587705572e+089 */ 39*41806Sbostic { 0x65154fdd, 0x7f73bf3f } /* 8.63616855509445e+178 */ 40*41806Sbostic }; 41*41806Sbostic #else 42*41806Sbostic double _exp5[] = { 43*41806Sbostic 5., 44*41806Sbostic 25., 45*41806Sbostic 625., 46*41806Sbostic 390625., 47*41806Sbostic 152587890625., 48*41806Sbostic 23283064365386962890625., 49*41806Sbostic #ifdef IEEE 50*41806Sbostic 5.4210108624275231e+044, 51*41806Sbostic 2.9387358770557196e+089, 52*41806Sbostic 8.6361685550944492e+178, 53*41806Sbostic #endif 54*41806Sbostic }; 55*41806Sbostic #endif 56*41806Sbostic 57*41806Sbostic double 58*41806Sbostic atof(p) 59*41806Sbostic register char *p; 60*41806Sbostic { 61*41806Sbostic extern double ldexp(); 62*41806Sbostic register c, exp = 0, eexp = 0; 63*41806Sbostic double fl = 0, flexp = 1.0; 64*41806Sbostic int bexp, neg = 1, negexp = 1; 65*41806Sbostic 66*41806Sbostic while((c = *p++) == ' '); 67*41806Sbostic if (c == '-') neg = -1; else if (c == '+'); else --p; 68*41806Sbostic 69*41806Sbostic while ((c = *p++), isdigit(c)) 70*41806Sbostic if (fl < _twoemax) fl = 10*fl + (c-'0'); else exp++; 71*41806Sbostic if (c == '.') 72*41806Sbostic while ((c = *p++), isdigit(c)) 73*41806Sbostic if (fl < _twoemax) 74*41806Sbostic { 75*41806Sbostic fl = 10*fl + (c-'0'); 76*41806Sbostic exp--; 77*41806Sbostic } 78*41806Sbostic if ((c == 'E') || (c == 'e')) 79*41806Sbostic { 80*41806Sbostic if ((c= *p++) == '+'); else if (c=='-') negexp = -1; else --p; 81*41806Sbostic while ((c = *p++), isdigit(c)) eexp = 10*eexp + (c-'0'); 82*41806Sbostic if (negexp < 0) eexp = -eexp; exp += eexp; 83*41806Sbostic } 84*41806Sbostic bexp = exp; 85*41806Sbostic if (exp < 0) exp = -exp; 86*41806Sbostic 87*41806Sbostic for (c = 0; c < sizeof(_exp5)/sizeof(_exp5[0]); c++) 88*41806Sbostic { 89*41806Sbostic #ifdef hp300 90*41806Sbostic if (exp & 01) flexp *= *(double *)&_exp5[c]; 91*41806Sbostic #else 92*41806Sbostic if (exp & 01) flexp *= _exp5[c]; 93*41806Sbostic #endif 94*41806Sbostic exp >>= 1; if (exp == 0) break; 95*41806Sbostic } 96*41806Sbostic 97*41806Sbostic if (bexp < 0) fl /= flexp; else fl *= flexp; 98*41806Sbostic fl = ldexp(fl, bexp); 99*41806Sbostic if (neg < 0) return(-fl); else return(fl); 100*41806Sbostic } 101