《C程序设计语言》练习 4-2
2018-01-03 10:25
218 查看
练习 4-2
对 atof 函数进行扩充,使它可以处理形如
123.45e-6
的科学表示法,其中,浮点数后面可能会紧跟一个 e 或 E 以及一个指数(可能有正负号)。
原atof函数 :
扩充代码 :
sign2 : 用来记录指数的正负,若指数是负数则为 1,否则为 0
若数字后面有E则进入扩展代码
第一步是读取可能存在的符号位并记录下来,若没有符号位则默认正数
第二步读取指数,然后将指数保存到 n
第三步改变 power 的值,根据 sign2 来决定是增加 power ,还是减少 power
科学计数法 aEb
表示 a 乘以 10 的 b 次方
而 power 本身就是一个 10 的幂,而且最后 val 会除以 power,
所以我这里直接对 power 进行处理,用来解决科学计数法的问题
完整代码 :
这里的 printf 函数中 使用了 “%g”
g格式:自动选f格式或e格式中较短的一种输出,且不输出无意义的零。
因为浮点型运算的误差问题,如果直接用 “%f” 会输出很恶心的东西
printf 函数参考于 “77695的自留地”
关于printf()函数和浮点数
对 atof 函数进行扩充,使它可以处理形如
123.45e-6
的科学表示法,其中,浮点数后面可能会紧跟一个 e 或 E 以及一个指数(可能有正负号)。
原atof函数 :
double atof(char s[]) { double val, power; int i, sign; for (i = 0; isspace(s[i]); i++) /* skip white space */ ; 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; } /*-------------------------------- 扩充代码插入位置 --------------------------------*/ return sign * val / power; }
扩充代码 :
sign2 : 用来记录指数的正负,若指数是负数则为 1,否则为 0
double atof(char s[]) { double power, val; int sign, i, sign2, j, n; 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 = val * 10 + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = val * 10 + (s[i] - '0'); power *= 10; } //-------------------------------------------------- if (s[i] == 'e' || s[i] == 'E') { i++; sign2 = (s[i] == '-') ? 1 : 0; if (s[i] == '-' || s[i] == '+') i++; for (n = 0; isdigit(s[i]); i++) n = n * 10 + (s[i] - '0'); for (j = 0; j < n; j++) power = (sign2) ? (power * 10) : (power / 10); } //-------------------------------------------------- return val * sign / power; }
若数字后面有E则进入扩展代码
第一步是读取可能存在的符号位并记录下来,若没有符号位则默认正数
第二步读取指数,然后将指数保存到 n
第三步改变 power 的值,根据 sign2 来决定是增加 power ,还是减少 power
科学计数法 aEb
表示 a 乘以 10 的 b 次方
而 power 本身就是一个 10 的幂,而且最后 val 会除以 power,
所以我这里直接对 power 进行处理,用来解决科学计数法的问题
完整代码 :
这里的 printf 函数中 使用了 “%g”
g格式:自动选f格式或e格式中较短的一种输出,且不输出无意义的零。
因为浮点型运算的误差问题,如果直接用 “%f” 会输出很恶心的东西
printf 函数参考于 “77695的自留地”
关于printf()函数和浮点数
/*练习 4-2 对 atof 函数进行扩充,使它可以处理形如
123.45e-6
的科学表示法,其中,浮点数后面可能会紧跟一个 e 或 E 以及一个指数(可能有正负号)。
*/
#include <stdio.h>
double atof(char s[]);
int isspace(int x);
int isdigit(int x);
main()
{
char num[] = " 123.456e-6";
double atof(char num[]), d;
d = atof(num);
printf("%g\n", d);
}
double atof(char s[]) { double power, val; int sign, i, sign2, j, n; 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 = val * 10 + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = val * 10 + (s[i] - '0'); power *= 10; } //-------------------------------------------------- if (s[i] == 'e' || s[i] == 'E') { i++; sign2 = (s[i] == '-') ? 1 : 0; if (s[i] == '-' || s[i] == '+') i++; for (n = 0; isdigit(s[i]); i++) n = n * 10 + (s[i] - '0'); for (j = 0; j < n; j++) power = (sign2) ? (power * 10) : (power / 10); } //-------------------------------------------------- return val * sign / power; }
int isspace(int x)
{
return (x == ' ' || x == '\t' || x == '\n') ? 1 : 0;
}
int isdigit(int x)
{
return (x >= '0' && x <= '9') ? 1 : 0;
}
相关文章推荐
- 《C程序设计语言》练习 3-6
- 《C程序设计语言》练习 4-4
- 《C程序设计语言》学习笔记——练习1-20
- 《C程序设计语言》学习笔记——练习3-1
- 《C程序设计语言》练习 1-12
- 《C程序设计语言》练习 2-9
- 《C程序设计语言》------练习7-7、7-8
- 《C程序设计语言》练习 2-10
- 《C程序设计语言》练习 3-1
- 《C程序设计语言》练习 2-7
- 《C程序设计语言》练习3-3
- 《C程序设计语言》练习 4-5
- 《C程序设计语言》学习笔记——练习4-1
- 《C程序设计语言》练习 1-6,1-7
- 《C程序设计语言》练习 3-2
- 《C程序设计语言》学习笔记——练习2-3
- 《C程序设计语言》练习1-5
- 《C程序设计语言》练习1-10
- 《C程序设计语言》练习 2-8