0%

4-2:对atof函数进行扩充

文章时效性提示

本文发布于 466 天前,部分信息可能已经改变,请注意甄别。

《C程序设计语言》练习4-2
对atof函数进行扩充,使它可以处理形如
123.45e-6
的科学表示法,其中,浮点数后面可能会紧跟一个e或E以及一个指数(可能有正负号)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
double atof(char s[])
{
    double val,power;
    int i,sign;
    for (i=0; isspace(s[i]); i++)
    {
        ;//去除数字前边的空格
    }
    sign = (s[i] == '-') ? -1 : 1;//把这个数字前边的符号保存在sign里
    if (s[i] == '+' || s[i] == '-')
    {
        i++;//跳过符号位
    }
    for (val = 0.0; isdigit(s[i]); i++)
    {
        val = 10.0* val + (s[i] - '0');//得到小数点前边的数字
    }
    if (s[i] == '.')
    {
        i++;//跳过小数点
    }
    for (power = 1.0; isdigit(s[i]); i++)
    {
        val = 10.0 * val + (s[i] - '0');//得到小数点后边的数字,一并放在val中
        power *= 10.0;//之后要除掉的倍数,因为之前多乘了。
    }
    return sign * val / power;//返回符号*值/小数点后位数
}

思路

  1. 提供的atof函数已经可以处理e之前的部分,需增加对e后部分的处理。
  2. 跳过e符号,获得符号位Esign,最后得到指数j。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <ctype.h>
#include <math.h>
double atof(char s[]);
int main() {
    char s[] = "3.1415E10";
    double ret = atof(s);
    return 0;
}
double atof(char s[])
{
    double val,power;
    int i,sign;
    int Esign = 0,j = 0;
    for (i=0; isspace(s[i]); i++)
    {
        ;
    }
    sign = (s[i] == '-') ? -1 : 1;
    if (s[i] == '+' || s[i] == '-')
    {
        i++;
    }
    for (val = 0.0; isdigit(s[i]); i++)
    {
        val = 10.0* val + (s[i] - '0');
    }
    if (s[i] == '.')
    {
        i++;
    }
    for (power = 1.0; isdigit(s[i]); i++)
    {
        val = 10.0 * val + (s[i] - '0');
        power *= 10.0;
    }
    if (s[i] == 'e' || s[i] == 'E')//处理科学计数法
    {
        i++;//跳过e
        Esign = (s[i] == '-') ? -1 : 1;//获得符号位
        if (s[i] == '+' || s[i] == '-')
        {
            i++;//跳过符号
        }
        for (j=0; isdigit(s[i]); i++)
        {
            j = 10 * j + (s[i] - '0');//获得指数
        }
    }
    return sign * val / power * pow(10, Esign*j);
}