【C语言】浮点数的存储和精度丢失

前言

本章节我们来讲讲在C语言当中浮点数是如何存储的,为什么有的浮点数我们通过打印,会存在打印不完整,丢失精度的现象。我们来看一段关于浮点数存储和整数存储的代码:

#include<stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);

	*pFloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);

	return 0;
}

这段代码运行之后输出结果是什么呢?
在这里插入图片描述
为什么 *pFlaot = 0.000000
为什么num = 1091567616
这就需要我们通过底层的浮点数存储和整数存储来解释。

整数存储

整数的存储就是用简单的二进制来存储,存储的是二进制的补码,但是打印的是二进制的原码,正数的原反补码都相同,但是负数的补码为原码取反加1,因为前些章节讲过,不过多解释整数的存储。

浮点数的存储

浮点数的存储是根据国际标准IEEE(电器和电子工程协会)754的规定来存储的,规定如下:
在这里插入图片描述
举例来说:
十进制的5.5,写成二进制是101.1,相当于1.011x2^2.
那么,按照上面V的格式,可以得出S=0,M=1.011,E=2。
十进制的-5.5,写成二进制是-101.1,相当于-1.011x2^2。那么,S=1,M=1.011,E=2。
在这里插入图片描述
IEEE 754规定:
对于32为的浮点数(flaot),最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M。
对于64位的浮点数(double),最高的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。
在这里插入图片描述
在这里插入图片描述

浮点数存储的过程

IEEE 754 对有效数字M和E,还有一些特别的规定
前面说过,1≤M<2,也就是说,M可以写成1.xxxxxx的形式,其中xxxxxx表示小数部分。IEEE 754 规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01时候,只保存01,等到读取的时候,再把第一位的1加上去,这样就能节省一个有效数字。以32位浮点数存储为例,留给M只有23位,将第一位的1舍去之后,等于可以保存24位有效数字。
为什么M位数越多,精度越高呢?
这里要讲到浮点数的小数位到底是怎么计算的,他不是简单整数位的二进制运算,就拿5.5和5.75为例:他们的二进制分别为101.1和101.11
在这里插入图片描述
所以小数点后面数字,是前一位数字除以2的结果这就有可能存在,某一些小数通过二进制无法准确表示,总会相差一点点,就是无法用准确的二进制表达出来
所以当我们M的位数越多,那么小数越精确,所以我们省下第一位的1这样在float浮点数存储下就能保存24位有效数字。
对于指数E,情况比较复杂,首先E是一个无符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0-255;如果E为11位,他的取值范围为0-2047.但是我们知道,科学计数法中的E时可以出现负数的,例如:0.11的二进制科学计数法为:1.1*2^-1,这里E是-1,就是负数,所以IEEE 754 规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。我们还用5.5来举个例子:
在这里插入图片描述
那么到底是不是这样存储的呢?我们用VS2022来求证一下
在这里插入图片描述
我们可以看到,确实是这种存储方式,因为vs是小端存储所以内存要倒着看,就是0x 40b00000和我们上面讲的完全吻合。

浮点数取的过程

指数E从内存中取出来还可以再分成三种情况:
E不全为0或不全为1
这时,浮点数就采用下买你的规则表示,E直接减去127(或1023),得到真实值,再将有效数字M前加上第一位的1.简单来说,怎么存的就怎么取。这个也是最基本的取出的方式
E全为0
这时,因为E是加上了一个中间值才为0所以E原本是-127(或-1023),所以是一个2^-127是很小很小的一个数字,无限接近于0.所以这个时候有效数字M不再加上第一位的1,二十还原成0.xxxxxx的小数。
E全为1
同理,全是1的话原E是126(或1024),是一个2^126很大的一个数字。
关于浮点数的表示规则就说到这里,这些我们简单了解即可,毕竟有些些复杂,我们来看开头的题目

题目解析

在这里插入图片描述
在这里插入图片描述
这道题根据不同的存储方式,读取规则不同,存储方式也不同所以打印出来的就不一样,这就是浮点数存储和整数存储,他们虽然都是二进制存储,但是规则完全不一样!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值