atof函数,可以处理科学计数法

  • 格式:pdf
  • 大小:71.16 KB
  • 文档页数:7

下载文档原格式

  / 7
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

156 else 157 while(expn-- > 0) 158 val = val / 10.0; 159 } 160 161 return val; 162 }*/
分析: 1, if(s[i] == 'e' || s[i] == 'E')中,如果写成 s[i++] == 'e' || s[i++] == 'E',if(s[i] == '-') 则当输入的字符串带有 E 时,不能正确得到结果,这是因为在一个语 句中使用两次自增操作,引起歧义 2, 当处理含有 e 或 E 情况时,参考的 atof 函数代码比自定义的 atof 函 数的代码要简洁,直观 3, 在参考的 atof 函数中, 用 val 去除 10 而不是用 val 乘以 0.1 的原因: 0.1 无法用二进制数精确地表示出来,大多数机器上 0.1 的二进制表示法都要比 0.1 稍微小一点,用 10.0 乘以 0.1 并不 能精确地得到 1.0,虽然两种做法都有误差,但是 连续的“除以 10”比连续的“乘以 0.1”更精确
另一版本 float atof(char *c) { float f=0,t=0,te=1; int i,op=1,eop=0,ep=0,cf=0;; for (i = 0; c[i]; i++) { if (c[i]=='.') { op=0; } if (c[i]=='e'||c[i]=='E') { eop=1; op=2; } if (eop&&c[i]=='-') { cf=1; } else if (eop&&c[i]=='+') { cf=0; } if (op==1&&c[i]>='0'&&c[i]<='9') { f=f*10+(c[i]-'0'); } else if(!op&&c[i]>='0'&&c[i]<='9'){ te*=10; t=t*10+c[i]-'0'; } else if (eop&&c[i]>='0'&&c[i]<='9') { ep=ep*10+c[i]-'0'; } } f=f+t/te; te=1; for (i = 0; i<ep; i++) { te*=10; } if (cf) { return f/te; } else return f*te;
源自《The C Programming Language》P62 pr4-2,代码位于 ex4.2 中: 对 atof 函数进行扩充,使它能够处理形如:123.45e-6 的科学表示法,其 中浮点数后面可能会紧跟一个 e 或 E 以及一个指数 代码: main.c 1 #include <stdio.h> 2 #include <ctype.h> 3 4 #define MAXLINE 100 5 6 int getLine(char s[], int lim); 7 double atof(char s[]); 8 int pow(int base, int expn); 9 10 int main() 11 { 12 13 char line[MAXLINE]; 14 int len; 15 while((len = getLine(line, MAXLINE)) > 0) 16 printf("%f\n", atof(line)); 17 //printf("the size of double: %d\n", sizeof(double)); 18 //printf("the size of float: %d\n", sizeof(float)); 19 20 return 0; 21 } 22 23 int getLine(char s[], int lim) //从终端获取一行字符 24 { 25 26 int i; 27 int c; 28 29 for(i = 0; --lim > 0 && (c = getchar()) != EOF && c != '\n'; ++i) 30 s[i] = c; 31 if(c == '\n')
32 33 34 35 36 37 38 39 值 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
s[i++] = c; s[i] = '\0'; return i; } int pow(int base, int expn) { int i; int sum; sum = 1; for(i = 0; i < expn; ++i) sum = sum * base; return sum; } double atof(char s[]) { int i; int sign; int flag; int expn; double val; double power; sign = 1; flag = 0; power = 1.0; expn = 0; for(i = 0; isspace(s[i]); ++i) ; if(s[i] == '-') sign = -1; if(s[i] == '+' || s[i] == '-') ++i; for(val = 0.0; isdigit(s[i]); ++i) val = val * 10.0 + (s[i] - '0'); //将字符串 s 转换成 double 型的浮点数 //底数为 base,指数为 expn 的指数求
75 76 77 78 79 80 81 82 83 84 85
ห้องสมุดไป่ตู้
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 power = pow(10, flag); 105 return sign * val / power; 106 107 } 108 109 110 111 /******************************************************************** ***** 112 参考代码:atof 113
}
又一版本: double atof_e(const char*s) { double val,val2,power; int sign,sign2,i; //去掉字符串中的空格 for(i=0;isspace(s[i]);++i) ; //判断正负数 ,并将 i 指向下一个位置 sign = (s[i] == '-') ? -1:1; if(s[i] == '+' || s[i] == '-') i++; //取浮点数的整数部分 for(val=0.0;isdigit(s[i]) && s[i] !=0;++i) val = 10*val+s[i]-'0'; //取小数点 if(s[i] == '.') i++; //后一个位置 //取小数点后面数 for(power=1.0;isdigit(s[i]) && s[i] !=0;++i) { val = 10*val+s[i]-'0'; power*=10; //小树的位数 } //处理 e 后面的数字 if(s[i]=='e' || s[i]== 'E') i++; sign2 = (s[i++] == '-') ? -1:1; for(val2=0.0;isdigit(s[i]) && s[i] !=0;++i) val2 = 10*val2+s[i]-'0'; if(sign2 == -1) return sign*val /power/pow(10,val2); else return sign*val*pow(10,val2)/power; }
********************************************************************* ****/ 114 /*double atof(char s[]) 115 { 116 117 int i; 118 int sign; 119 //int flag; 120 int expn; 121 double val; 122 double power; 123 124 sign = 1; 125 //flag = 0; 126 power = 1.0; 127 expn = 0; 128 for(i = 0; isspace(s[i]); ++i) 129 ; 130 if(s[i] == '-') 131 sign = -1; 132 if(s[i] == '+' || s[i] == '-') 133 ++i; 134 for(val = 0.0; isdigit(s[i]); ++i) 135 val = val * 10.0 + (s[i] - '0'); 136 if(s[i] == '.') 137 ++i; 138 for(; isdigit(s[i]); ++i) 139 { 140 val = val * 10.0 + (s[i] - '0'); 141 power = power * 10.0; 142 //++flag; 143 } 144 val = sign * val / power; 145 146 if(s[i] == 'e' || s[i] == 'E') 147 { 148 sign = (s[++i] == '-') ? -1 : 1; 149 if(s[i] == '+' || s[i] == '-') 150 ++i; 151 for(expn = 0; isdigit(s[i]); ++i) 152 expn = expn * 10.0 + (s[i] - '0'); 153 if(sign == 1) 154 while(expn-- > 0) 155 val = val * 10.0;
if(s[i] == '.') ++i; for(; isdigit(s[i]); ++i) { val = val * 10.0 + (s[i] - '0'); //power = power * 10.0; ++flag; } if(s[i] == 'e' || s[i] == 'E') //如果写成 s[i++] == 'e' || s[i++] == 'E',if(s[i] == '-') //则当输入的字符串带有 E 时, 不 能正确得到结果,这是因为在一 //个语句中使用两次自增操作, 引 起歧义 if(s[++i] == '-') { ++i; for(; isdigit(s[i]); ++i) expn = expn * 10 + (s[i] - '0'); expn = expn + flag; power = pow(10, expn); return sign * val / power; } else { for(; isdigit(s[i]); ++i) expn = expn * 10 + (s[i] - '0'); expn = expn - flag; power = pow(10, expn); return sign * val * power; }