读《C程序设计语言》笔记11

发现字符串处理真是太多了,之前写了字符串转整型,整型转字符串,今天要字符串转浮点数;

  题目要求:

  写一个字符串转浮点数的函数,使它可以处理形如:123.45e-6的科学表示法,其中,浮点数后面可能会紧跟一个e或E以及一个指数(可能有正负号)。

#include <stdio.h>

#include <ctype.h>



double strtofloat(char s[])

{

	double val, power;

	int exp, 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.0;

	}

	val= sign*val/power;

	

	if(s[i]=='e' || s[i]=='E')

	{

		sign=(s[++i]=='-') ? -1 : 1;

		if(s[i]=='+' || s[i]=='-')

			i++;

		for(exp=0; isdigit(s[i]); i++)

			exp= 10*exp + (s[i]-'0');

		if(sign==1)

			while(exp-- >0)		//positive exponent

				val*=10;

		else

			while(exp-- >0)		//negative exponent

				val/=10;

	}

	return val;

}



int main()

{

	char s[]="123.45e3";

	printf("%0.2f\n",strtofloat(s));

	system("pause");

	return 0;

}

执行结果如下:

  读《C程序设计语言》笔记11

结果保留了小数点后两位,函数的前半部分可以处理一般的字符串,形如"123.54",加上后半部分就可以处理科学表示法的了。

在处理科学表示法,e为负的情况下,val要除以10.

  为什么呢?用val去除以10而不是用val去乘以0.1的原因是:0.1无法用二进制数精确地表示出来,这就是著名的浮点数精度问题。比如表示***.4,除去前面的整数,我们直接看后面的小数部分:0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……,貌似永远算不完啊,实际直到加上前面的整数部分算够53位就行了。隐藏位技术:最高位的1不写入内存(最终保留下来的还是52位)。

  在大多数机器上,0.1的二进制表示法都要比0.1稍微小一点,用10.0乘以0.1并不能精确地得到1.0。从结果上看,虽然两种做法都会有一定的误差,但连续地“除以10”要比连续地“乘以0.1”更精确。

你可能感兴趣的:(程序设计)