题目:
对atof函数进行扩充,使它可以处理形如 123.45e-6的科学表示法,其中,浮点数后面可能会紧跟一个e或者E以及一个指数(可能有正负号)
自我解答:
首先看下书本中的atof函数:
#include <stdio.h>
#include <ctype.h>
double atof(char s[])
{
int i, sign;
double var, power;
for(i = 0; isspace(s[i]); i++);
sign = (s[i] == '-') ? -1 : 1;
if(s[i] == '-' || s[i] == '+')
i++;
for(var = 0.0; isdigit(s[i]); i++)
{
var = var * 10.0 + s[i] - '0';
}
if(s[i] == '.')
i++;
for(power = 1.0; isdigit(s[i]); i++)
{
var = var * 10.0 + s[i] - '0';
power *= 10.0;
}
return sign * var / power;
}
对其改进后
#include <stdio.h>
#include <ctype.h>
double atof(char s[])
{
int i, sign, exp, signExp;
double var, power, divider;
divider = 1.0;
for(i = 0; isspace(s[i]); i++);
sign = (s[i] == '-') ? -1 : 1;
if(s[i] == '-' || s[i] == '+')
i++;
for(var = 0.0; isdigit(s[i]); i++)
{
var = var * 10.0 + s[i] - '0';
}
if(s[i] == '.')
i++;
for(power = 1.0; isdigit(s[i]); i++)
{
var = var * 10.0 + s[i] - '0';
power *= 10.0;
}
if(s[i] == 'e')
{
i++;
signExp = (s[i] == '-') ? 0 : 1;
if(s[i] == '-' || s[i] == '+')
i++;
for(exp = 0; isdigit(s[i]); i++)
{
exp = exp * 10.0 + s[i] - '0';
}
if(signExp)
for(divider = 1.0; exp > 0; exp--)
divider *= 10.0;
else
for(divider = 1.0; exp > 0; exp--)
divider /= 10.0;
}
return sign * var * divider / power;
}
int main()
{
char s[] = "123.45e+6";
printf("%f\n", atof(s));
}
修改思路是接着书中atof的末尾进行进一步判断,如果是字母e,则进一步判断e后面是正负号,接着取出指数数字,根据指数正负号的不同,计算divider的值,当指数位是正数时,divider = 10^exp,如果指数是负数则divider = 10 ^-exp。最后把这个值乘以前面数字转化后的值。
注意:divider要初始化为1.0,这是为了避免没有e时也能正确的转换。如果不初始化为1.0,则编译器默认配置为0,则此时结果也为0.