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