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.2 (Berkeley) 04/12/91"; 14 #endif /* LIBC_SCCS and not lint */ 15 16 /* 17 * simple atof() for IEEE 754 architectures 18 */ 19 20 #include <machine/endian.h> 21 #include <stdlib.h> 22 #include <math.h> 23 #include <ctype.h> 24 25 static double twoemax = 9007199254740992.; /*2^53*/ 26 27 /* attempt to be as exact as possible */ 28 static struct { 29 long low_word; 30 long high_word; 31 } exp5[] = { 32 #if BYTE_ORDER == BIG_ENDIAN 33 { 0x40140000, 0x00000000 }, /* 5 */ 34 { 0x40390000, 0x00000000 }, /* 25 */ 35 { 0x40838800, 0x00000000 }, /* 625 */ 36 { 0x4117d784, 0x00000000 }, /* 390625 */ 37 { 0x4241c379, 0x37e08000 }, /* 152587890625 */ 38 { 0x4493b8b5, 0xb5056e17 }, /* 2.3283064365387e+022 */ 39 { 0x49384f03, 0xe93ff9f6 }, /* 5.42101086242753e+044 */ 40 { 0x52827748, 0xf9301d33 }, /* 2.93873587705572e+089 */ 41 { 0x65154fdd, 0x7f73bf3f } /* 8.63616855509445e+178 */ 42 #else /* BYTE_ORDER == LITTLE_ENDIAN */ 43 { 0x00000000, 0x40140000 }, /* 5 */ 44 { 0x00000000, 0x40390000 }, /* 25 */ 45 { 0x00000000, 0x40838800 }, /* 625 */ 46 { 0x00000000, 0x4117d784 }, /* 390625 */ 47 { 0x37e08000, 0x4241c379 }, /* 152587890625 */ 48 { 0xb5056e17, 0x4493b8b5 }, /* 2.3283064365387e+022 */ 49 { 0xe93ff9f6, 0x49384f03 }, /* 5.42101086242753e+044 */ 50 { 0xf9301d33, 0x52827748 }, /* 2.93873587705572e+089 */ 51 { 0x7f73bf3f, 0x65154fdd } /* 8.63616855509445e+178 */ 52 #endif 53 }; 54 55 double 56 atof(p) 57 register const char *p; 58 { 59 register int c; 60 register int exp = 0; 61 register int eexp = 0; 62 double fl = 0; 63 double flexp = 1.0; 64 int bexp; 65 int neg = 1; 66 int negexp = 1; 67 68 while (isspace(*p)) 69 ++p; 70 71 if ((c = *p++) == '-') 72 neg = -1; 73 else if (c == '+') 74 /* skip it */; 75 else 76 --p; 77 78 while ((c = *p++) && isdigit(c)) 79 if (fl < twoemax) 80 fl = 10 * fl + (c-'0'); 81 else 82 ++exp; 83 84 if (c == '.') 85 while ((c = *p++) && isdigit(c)) 86 if (fl < twoemax) { 87 fl = 10 * fl + (c-'0'); 88 --exp; 89 } 90 91 if (c == 'E' || c == 'e') { 92 if ((c = *p++) == '-') 93 negexp = -1; 94 else if (c == '+') 95 /* skip it */; 96 else 97 --p; 98 while ((c = *p++) && isdigit(c)) 99 eexp = 10 * eexp + (c-'0'); 100 if (negexp < 0) 101 eexp = -eexp; 102 exp += eexp; 103 } 104 105 bexp = exp; 106 if (exp < 0) 107 exp = -exp; 108 109 for (c = 0; exp && c < sizeof exp5 / sizeof exp5[0]; ++c) { 110 if (exp & 1) 111 flexp *= *(double *)&exp5[c]; 112 exp >>= 1; 113 } 114 115 if (bexp < 0) 116 fl /= flexp; 117 else 118 fl *= flexp; 119 120 fl = ldexp(fl, bexp); 121 122 return neg < 0 ? -fl : fl; 123 } 124