• 读《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;
    }
    

    执行结果如下:

      

    结果保留了小数点后两位,函数的前半部分可以处理一般的字符串,形如"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”更精确。

  • 相关阅读:
    数据库中生成UUID的方式
    db2如果修改主机名之后
    linux修改主机名
    db2动态查看备份进度
    oracle-DG
    linux环境变量和对应文件的生效顺序
    数据泵与传统exp/imp对比
    oracle之ogg部署(RAC到单机)
    oracle之ogg部署(单机到单机)
    达梦 (实时主备+数据守护)测试
  • 原文地址:https://www.cnblogs.com/wangzhiyu811/p/2108471.html
Copyright © 2020-2023  润新知