Double为什么存不了-水蒸气热阻 0.000017134

浮点数在内存中的存储机制和整型数不同,其有舍入误差,在计算机中用近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学记数法。
所以浮点数在运算过程中通常伴随着因为无法精确表示而进行的近似或舍入。但是这种设计的好处是可以在固定的长度上存储更大范围的数。
1、将字符串转换为float、double过程存在精度损失,只是float、double各自损失的精度不相同而已
std::string str=&8.2&;
float cc=atof(str.c_str());& //cc的值为8.1999998
std::string str=&8.2&;
double cc=atof(str.c_str());& //cc的值为8.9993
2、将float、double转换为字符过程中可能存在精度损失,但是通过%.8lf可以规避
(1)float小数点前后加起来有效数字只有6位。当给定的float有效数在6位以内转换为字符不会丢失精度,当有效位数大于6位就会存在精度丢失
//精度没有丢失
char buf[100]={'\0'};
float aa=8000.25;
sprintf(buf,&%f&,aa);&& //
//精度没有丢失
char buf[100]={'\0'};
float aa=8.00025;
sprintf(buf,&%f&,aa);&& buf = 8.000250
//精度丢失,存在误差
char buf[100]={'\0'};
float aa=;
sprintf(buf,&%f&,aa);& //
//精度丢失,存在误差此时使用.8lf也无效
char buf[100]={'\0'};
float aa=;
sprintf(buf,&%.8lf&,aa); //6
(2)double小数前后加起来的有效数字只有16位,当给定的double有效数在16位以内转换为字符串不会丢失精度,当有效位数大于16位湖影公寓存在精度丢失
char buf[100]={'\0'};
double aa=121.012;
sprintf(buf,&%.20lf&,aa); //121.
//没有误差
char buf[100]={'\0'};
double aa=;
sprintf(buf,&%.8lf&,aa);
std::cout &&buf&&std:: //0
3、浮点数比较
用&==&来比较两个double应该相等的类型,返回真值完全是不确定的。计算机对浮点数的进行计算的原理是只保证必要精度内正确即可。
我们在判断浮点数相等时,推荐用范围来确定,若x在某一范围内,我们就认为相等,至于范围怎么定义,要看实际情况而已了,float,和double 各有不同
所以const float EPSINON = 0.00001;
if ((x &= - EPSINON) && (x &= EPSINON) 这样判断是可取的
至于为什么取0.00001,可以自己按实际情况定义
根据上面分析建议在系统开发过程中设计到字符转换建议采用double类型,精度设置为%.8lf即可,在比较浮点数十建议EPSINON = 0.
相关文章列表:float和double的数值怎么保存在二进制中_ASP.NET技巧_动态网站制作指南
float和double的数值怎么保存在二进制中
来源:人气:22
稍微浅学过二进制的人,都清楚二进制是个什么东西。我们都了解正整数是怎么转化成二进制的,那么计算机中,又是怎么保存folat,double类型的数值的呢?
要像弄清楚这个问题,首先得清楚二进制是怎么表示小数的。(这一点请注意了)
十进制是怎么表示小数的呢?
比如,125.456&&&& 其实可以分解成 1*10^2+2*10^1+5*10^0+4*10^-1+5*10^-2+6*10^-3
如果用指数表示的话就是&& 1.25456E2--------(1+2*10^-1+5*10^-2+4*10^-3+5*10^-4+6*10^-5)*10^2
了解清楚了上面的关系,那么二进制中的小数表示应该也很清楚了
0.1---------------------------等于--------------------1*2^-1(0.5)
0.01-------------------------等于--------------------1*2^-2(0.25)
0.001-----------------------等于--------------------1*2^-3(0.125)
0.0001---------------------等于--------------------1*2^-4 (0.0625)
0.00001-------------------&&&&&&& --------------------1*2^-5 (0.03125)
那么任意一个带小数的二进制表示我们都可以表示成这样,例如
----------------等于-------------1*2^4+1*2^0+1*2^-1+1*2^-3
用指数表示为1.^4----------(1+1*2^-4+1*2^-5+1*2^-7)*2^4
接下来就很清楚了,任意一个十进制的数值都可以表示成或者近似表示成(1+1*2^-n+...1*2^-m)*2^k
例如:8.5=1*2^4+1*2^-1
&&&&&&&&&& 5.4约等于4+1+0.25+0.125+0.*2^2+1*2^0+1*2^-2+1*2^-3+1*2^-6
&&&&&&&&&&(这也解释了为什么二进制是不能精确表示1/10,因为无论加多少阶,1/10都不能被上述样式精确表示出来。有些时候也会出现能够除尽的算式,计算机中却不能除尽例如:double f1=3240.0;
&&&&&&& double f2=8.0;
&&&&&&& double f3=(f1*(f2/100))/(1+(f2/100));//结果应该为240
&&&&&&& System.out.intln(f3);输出结果为239.97
&&&&&& 这点参考自:/03/.html)
总结:现在我们知道了二进制是怎么表示小数,并且任何十进制的数都可以等于或近似表示成(1+1*2^-m+...1*2^-n)*2^k。
那么剩下的就很简单了。我们只要知道:
&&&&&&& float有4个字节32为,首位表示符号,接下来8位表示阶数K,剩下23表示二进制的小数部分。
&&&&&&& double有8个字节,64位,首位表示符号,11位表示阶数k,剩下表示小数部分。
更详细的表示方法,别人已经写了,详见:
http://blog.csdn.net/gjw198276/article/details/6956244
完!!欢迎吐槽和评论,敬请指出不足之处!!!
优质网站模板

我要回帖

更多关于 0.00001科学计数法 的文章

 

随机推荐