|
1 | 1 | /*
|
2 | 2 | * Exercise 4-2. Extend atof to handle scientific notation of the form
|
3 |
| - * 123.45e-6 |
| 3 | + * |
| 4 | + * 123.45e-6 |
| 5 | + * |
4 | 6 | * where a floating-point number may be followed by e or E and an optionally
|
5 |
| - * signed exponent. |
| 7 | + * signed exponent. |
| 8 | + * |
6 | 9 | * By Faisal Saadatmand
|
7 | 10 | */
|
8 | 11 |
|
9 | 12 | #include <stdio.h>
|
10 | 13 | #include <ctype.h>
|
11 |
| -#include <math.h> |
12 | 14 |
|
13 | 15 | /* functions */
|
14 | 16 | double atof(char []);
|
15 | 17 |
|
16 | 18 | /* atof: convert string s to double */
|
17 | 19 | double atof(char s[])
|
18 | 20 | {
|
19 |
| - int i, sign, expSign; |
| 21 | + int i, sign, expSign; |
20 | 22 | double val, power, exponent;
|
21 | 23 |
|
22 |
| - for (i = 0; isspace(s[i]); ++i) /* skip whitespace */ |
| 24 | + for (i = 0; isspace(s[i]); ++i) /* skip whitespace */ |
23 | 25 | ;
|
24 | 26 |
|
25 | 27 | sign = (s[i] == '-') ? -1 : 1;
|
26 | 28 | if (s[i] == '+' || s[i] == '-')
|
27 | 29 | ++i;
|
28 | 30 |
|
29 |
| - for (val = 0.0; isdigit(s[i]); i++) |
| 31 | + for (val = 0.0; isdigit(s[i]); ++i) |
30 | 32 | val = 10.0 * val + (s[i] - '0');
|
31 | 33 |
|
32 | 34 | if (s[i] == '.')
|
33 |
| - i++; |
| 35 | + ++i; |
34 | 36 |
|
35 |
| - for (power = 1.0; isdigit(s[i]); i++) { |
| 37 | + for (power = 1.0; isdigit(s[i]); ++i) { |
36 | 38 | val = 10.0 * val + (s[i] - '0');
|
37 | 39 | power *= 10.0;
|
38 | 40 | }
|
39 | 41 |
|
40 |
| - if (s[i] != '\0') { /* handle scientific notation */ |
41 |
| - if (s[i] == 'e' || s[i] == 'E') |
42 |
| - ++i; |
43 |
| - else |
44 |
| - return -1; |
| 42 | + if (tolower(s[i]) == 'e') /* handle scientific notation */ |
| 43 | + ++i; |
45 | 44 |
|
46 |
| - expSign = (s[i] == '-') ? -1 : 1; /* record the exponent sign */ |
47 |
| - if (s[i] == '+' || s[i] == '-') |
48 |
| - ++i; |
| 45 | + expSign = (s[i] == '-') ? -1 : 1; /* record exponent's sign */ |
| 46 | + if (s[i] == '+' || s[i] == '-') |
| 47 | + ++i; |
49 | 48 |
|
50 |
| - for (exponent = 0.0; isdigit(s[i]); i++) /* extract the exponent */ |
51 |
| - exponent = 10.0 * exponent + (s[i] - '0'); |
| 49 | + for (exponent = 0.0; isdigit(s[i]); i++) /* extract the exponent */ |
| 50 | + exponent = 10.0 * exponent + (s[i] - '0'); |
52 | 51 |
|
53 |
| - return (sign * val / power) * pow(10, expSign * exponent); |
| 52 | + while (exponent-- != 0) /* adjust power according to exponent */ |
| 53 | + power = (expSign > 0) ? power / 10: power * 10; |
54 | 54 |
|
55 |
| - } else |
56 |
| - return sign * val / power; |
| 55 | + return sign * val / power; |
57 | 56 | }
|
58 | 57 |
|
59 | 58 | int main(void)
|
60 | 59 | {
|
61 |
| - char number[64] = { "123.45" }; |
62 |
| - char number2[64] = { "123.45e-6" }; |
63 |
| - char number3[64] = { "123.45e+6" }; |
| 60 | + char number[] = "123.45"; |
| 61 | + char number2[] = "123.45e-6"; |
| 62 | + char number3[] = "123.45e+6"; |
| 63 | + char number4[] = "-123.45E+6"; |
64 | 64 |
|
65 | 65 | printf("%f\n", atof(number));
|
66 | 66 | printf("%f\n", atof(number2));
|
67 | 67 | printf("%f\n", atof(number3));
|
| 68 | + printf("%f\n", atof(number4)); |
68 | 69 |
|
69 | 70 | return 0;
|
70 | 71 | }
|
0 commit comments