当前位置:首页 » 《资源分享》 » 正文

细谈浮点数与0的比较_Mr.shenwang的博客

27 人参与  2021年10月30日 13:23  分类 : 《资源分享》  评论

点击全文阅读


目录

引言

有趣的现象

精度损失

两个浮点数的比较

浮点数与0的比较

 总结


引言

在细谈浮点数与0比较之前,我们要引入一个小概念“浮点数是如何存储的”,我们知道整型在计算机中存储的是二进制,那么浮点数呢,是否也一样呢?我们看个例子:

int main()
{
	int n = 9;
	float *pfloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pfloat的值为:%f\n", *pfloat);

	*pfloat = 9.0;
	printf("n的值为:%d\n", n);
	printf("*pfloat的值为:%f\n", *pfloat);
	return 0;
}

 猜猜这些会分别输出什么?

明明*pfloat存储的与n存的值一样,但打印出来却相差这么多,这是因为浮点型与整型存储方式不同。

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数可以表示为下面的形式:

(-1)^S*M*2^E

1.(-1)^S表示符号位,当S=0时,表示正数,当S=1时,表示负数。

2.M表示有效数字,大于等于1,小于2。

3.2^E表示指数位。

如:9.0可表示为1001.0

       0.5可表示为0.1,注意这里小数点前直接按照二进制写出,小数点后为2的-n次方,n表小数点后的第几位。再比如0.125可表示为0.001。

IEEE 745规定:对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

IEEE 754对有效数字M和指数E,还有一些特别规定。

有效数字M:

1<M<2,也就是说,M写成1.xxxxxxx的形式,其中xxxxxxx表示小数部分。

而为了扩大M的取值范围,增加它的位数,IEEE 754规定,在计算机内部保存M时,因为浮点数的第一位总是1,可以被舍去,只保存小数部分,而在取出来时在添上。比如保存1.011时,只保存011,后面的位数补0就可以了,等到读取的时候,再把第一位的1补上去。

指数E:

首先,E为一个无符号整数(unsigned int)

如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法是可以出现负数的,所以IEEE 754又规定,存入内存的E是真实值加上一个中间数,对于8位的E,中间数是127,对于11位的E,中间数是1023。比如,2^2的E是2,所以保存为32位浮点数时,必须保存为2+127=129,即10000001。

然后,指数E还有两种特殊情况:

E全为0

E的二进制为全为0代表原来的E是-127,这意味着什么,2的127次方是一个无穷大的数,而1再除以127说明这个数已经无限趋近与0了。这时,浮点数的指数E等于1-127(或1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxxx的小数。这样做是为了表示正负零,以及接近于0的很小的数字。

E全为1

E的2进制全为1,11111111,也就是原来的E值为128,2的128次方是一个很大的数,因此我们也认为,有效数字M不再加上第一位的1,再加上符号位S,就表正负无穷大的数字了。

于是我们回到原来的例题。

再打开我们的计算器与之前的对比

发现结果就是这个,那么浮点型存储讲完。

有趣的现象

在偶然试验中,我定义了一个double类型的数观察它后50位的数字发现差距很大:

于是我们又引入了一个概念,精度损失。

精度损失

精度:精度是引起数据变化的最小值。

我们查阅资料发现float的精度为6位,double的精度为15位。这是为什么呢,因为在浮点数存储时,它不可能完全与原来的数一模一样,计算机只识别0和1,而2的指数次幂它不可能表示到所有的数。举个例子,用刚讲的浮点型存储表达0.1:

 因为M只有23位,而0.1的二进制远远不止23位,会发生截断,只取23位,这也就是为什么浮点型存储会有精度损失。

而精度损失造成的后果可能会变大也可能会变小,因为在存储截断也可能会发生四舍五入进位。

两个浮点数的比较

因为精度损失,两个浮点数也就不能用==来进行比较,再举个例子:

于是在比较两个浮点数时我们要自行设置精度或者使用c语言自己定义的最小精度。

fabs是取一个数据的绝对值,而DBL_EPSILON是double类型的最小精度。

fabs的头文件是math.h,DBL_EPSILON的头文件是float.h。

至于为何要取绝对值,看下图:

两个相近浮点数相减的值在有效范围内,那么可以判定两个数相等。

浮点数与0的比较

知道了两个浮点数的比较后,我们自然就相知道浮点数与0的比较咯。

而通过类比推理只要一个浮点数减去0再与最小精度相比就能判定是否等于0。

而一个数减去0,就相当于它本身因此:

 总结

本文分享到此结束了,如果对你有帮助记得一键三连哦!!!

 

 

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/30278.html

浮点数  精度  数字  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1