浮点数在内存中的存储
1.浮点数存储进内存的规则:
(-1)^s *M*2^E
首先举个例子说明这个公式怎么用
float a=5.5;
5.5(十进制)转化为2进制为 101.1(0.5=1/2=2^-1)
用科学计数法表示这个数为1.011*2^2
s代表的是1或者0,用于判断是否为负数(符号位)
M代表的就是那个1.011
E代表的就是2^2中的2
用float举例s存放于红色框处;
蓝色框存放的是无符号的整型(占8个比特,如果是double则存放11个比特),存放的是E,绿色的框存放的就是M。
注意事项:1.为了提高精度,会默认的把M中的首位的1去除,以达到提高一个bit的精度。
2.因为蓝色框中存储的是无符号的整型,但是实际存储的时候可能有负数,所以规定先加127在放入。
3.M少的部分用0补充
2.对存储进内存进行取出的规则探讨:
2.1 E为非全0或1的数(常规情况)
先把E减去127得到原来的E,然后再在M的前面加个1.
2.2 E为全0
E就应该为-127,说明这个数贼小,就直接把E当作-126,(-1022double),M直接进行计算
2.3E为全1
则说明这个说为无穷大的一个数(这里就不进行探讨了)
3.例题解析:
int i=9;
float*pfloat=(float *)&i;
printf("%d",i);9
printf("%f",*pfloat); 0.000000
*pfloat=9.0;
printf("%d",i);1,091,567,616
printf("%p",ploat);9.0
(看这道题的答案和你想的,和你一开始认为的,你就能知道浮点数的存储和整数的存储是两套存储体系)
首先一开始把i的地址强制转化为了float*类型,但是并没有对他进行任何的处理,现在要打印的是有符号的整型%d,所以打印是看整数存储,出来的仍然是9;接着要以浮点数去打印这个数,现在i的存储在内存中的值并没有改变还是为:
0000 0000 0000 0000 0000 0000 0000 10001
把这个按照浮点数的方式进行取出
因为E存入为全0,所以这个数为-126次方,本来就贼小了,M也是前面一堆0;所以打印出来的结果为0.000000;
然后现在是解引用后对ploat进行赋值(在这个时候内存中的值就发生了改变)
9.0=(-1)^0*1.001*2^3
在内存中存储既为 0 1000 0010 0010 0000 0000 0000 0000 000
然后再以%d形式打印的时候,不就变成1,091,567,616这个数了吗?
接着,再以浮点数的形式打印,现在存入内存的,不就是浮点数9.0吗,所以打印出来的结果就是9.0。
4.对浮点型十进制数转化二进制数的转化方式进行探究:
2^-1=0.5
2^-2=0.25
....
在存入的过程就是个不断不断弥补的过程,所以,如果无法弥补,就可能造成误差。
要进行判断的时候需要这样进行
if(fabs(0.1+0.2-0.3)<0.0000001) 给一个偏差的精度
(fabs头文件为<math.h>)
原文地址:https://blog.csdn.net/2301_81172092/article/details/142592366
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!