首页 > 系统相关 >C语言进阶【5】---数据在内存中的存储【2】(小数存储很难吗?)

C语言进阶【5】---数据在内存中的存储【2】(小数存储很难吗?)

时间:2024-09-22 18:49:17浏览次数:10  
标签:存储 进阶 32 浮点数 C语言 printf pFloat 小数

本章概述

本章引要

常见的浮点数:3.1415,1E10等。其中,1E10是科学计数法的形式,它也就等于1*10^10小数数据类型:float ,double ,long double

练习

在开讲本章内容前,大家先来看个代码,大家先猜一下结果:

#define  _CRT_SECURE_NO_WARNINGS	1
#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("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

结果运行图:在这里插入图片描述
不知道大家猜对多少个答案?最起码要猜对两个答案吧。

浮点数的存储

在上面的代码中,n*pFloat指的是同一个空间里面的数据,但是两者取出来的数据差别很大说明两者的存储和取出数据的方式差别很大,整形的数据存储咱们已经讲过了,现在来讲一下浮点数的存储方式。
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:在这里插入图片描述
举个例子:

// 5.5 的二进制表示形式: 101.1
小数点前面: 1*2^2+0*2^1+1*2^0
小数点后面: 1*2^-1
小数就为:1*2^2+0*2^1+1*2^0+1*2^-1
我们知道,2^-1为0.5.
所以,小数点前面都是2的非负整数次方,小数点后面都是负整数次方。

小数存储的格式并不是我们所写的 101.1这个格式,而是按照上面的IEE754标准进行存储的。按照这个标准写的格式为:(-1)0 * 1.011* 22。其实就是个科学计数法的表现形式 。那么,按照上面的标准表示的话,S=0 ,M=1.011 ,E=2。在内存中,我们浮点数存储的有价值的数据就是S ,M和E

  • IEEE754标准规定如下
    • 对于32位的浮点数(32位机器平台),最高的1位存放的是符号位S紧跟着8位存储的是指数位E,再紧跟着的23位存储的有效值M。
    • 对于64位的浮点数(64位机器平台),最高的1位存放的是符号位S,紧跟着11位存储的是指数位E,在紧跟着52位存储的是有效值M。如图所示的存储图:在这里插入图片描述
  • IEEE754标准对E和M有些特殊规定:
    • M的特殊规定:由IEEE754标准规定,1<=M<2,也就是说所有的浮点数有效值位M必须是 1.xxxxxxx。其中 .xxxxx是小数位。IEEE754标准规定,在计算机中,对于有效值位M,只存储小数部分,整数部分的1省略(不进行存储)当读取数据的时候,再把1给加上。这样做,可以扩大小数的存储范围,使存储的精度增高
    • E的特殊规定由IEEE754标准规定的指数E是一个无符号整数(unsigned char类型),因为在浮点数的存储中,只有一个符号位,没有第二个符号位,所以,除了高位1位的符号位,剩下的全是数值位——E为无符号整形。在32位平台下的取值范围为0~255,在64位平台下的取值范围为0 ~2047.但是,我们知道,科学计数法中的指数是有负数的。比如:
0.5 的二进制表示 :0.1
IEEE754标准形式:(-1)^0*1* 2^-1
这个时候指数E就是负数 -1

为了符合科学计数的表现形式IEEE754标准规定,存入内存时,E的真实值必须再加上一个中间数,对于32位平台,这个中间数是127,对于64位平台,这个中间数是1023。比如(32位平台),2^10,E为10,我们存储的是:E+127=137,即10001001.

浮点数的取出

我们存储的是S,E和M,所以我们直接取出这三个值就OK了。然后,再按照IEEE754标准还原为小数,就可以得到我们想要的值了。对于,S和M这俩值的取出没什么特别的,正常取出就OK了,其中,别忘了取出M值的时候加上1.这里最特别的值是E,它的取值就要分三种情况讨论了,如下:

  • E不全为1或不全为0:我们取出E的值后,再减去127(32位平台)或者减去1023(64平台),才能得到真正的指数E(上面讲过了E的存储)。比如,0.5的存储。
0.5的二进制位 :0.1
IEEE745的形式:(-1)^0*1.0*2^-1    s=0 ,m=1.0 ,E=-1+127=126
0 01111110 00000000000000000000000 (小数部分全是0)
  • E全为0:当E的存储全为0的时候,IEEE745规定,原本的E=1-127=-126(32位平台)或E=1-1023(64位平台)。这个时候,有效值M不在加1,这样做是为了表示0或接近0的很小很小的小数。如下所示:。
0 00000000 00100000000000000000000
  • E全为1:这个时候说明这个小数是个很大很大的数。(正负取决于符号位S),如下所示:
0 11111111 0010000000000000000000

小补充

前面,咱们举的小数都是较容易表示二进制的。假如,我们举个较难表示的小数:5.54

5.5还是比较容易表示的 :101.1 
但是,0.04要怎样表示呢?2^-2结果是0.25,比0.04大太多了
					  2^-3结果是0.125 ,比0.04大。
					  ………………

从上面的例子中,我想告诉大家的是:浮点数在内存中是无法精确存储的。所以,对于那些较难表示的小数,计算机会在后面多输出几位(或着四舍五入),以便接近你想要的数据

题目解析

上面讲了很多的知识铺垫了,咱们也该回归开头的那个练习题了。。

int n=9;
float *pFloat = (float *)&n;
printf("*pFloat的值为:%f\n",*pFloat);
9的存储: 00000000 00000000 00000000 00001001
当执行到这个代码的时候 printf("*pFloat的值为:%f\n",*pFloat);就会把9的存储格式
当成小数的存储格式(数据类型的意义)
    S    E            M
即  0 00000000 0000000000000000000100
是E全为0的情况,有效值M不再加1,所以是个接近0的小数,又因为在32位平台下,输出小数点后6位,
所以输出结果:0.000000
//----------------------------------------//
*pFloat = 9.0;
 printf("num的值为:%d\n",n);
 9.0的存储格式: 1001.0
               (-1)^0*1.0010*2^3         E=3+127=130
               S       E               M
               0  10000010 00100000000000000000000
执行到这个代码的时候 printf("num的值为:%d\n",n);就会被当成有符号整数(数据类型的意义)
即   01000001 00010000 00000000 00000000 (正整数:原码,反码和补码相同)
输出结果:1091567616

彩蛋时刻!!!


https://www.bilibili.com/video/BV1Zd4y1A7yc/?spm_id_from=333.337.search-card.all.click&vd_source=7d0d6d43e38f977d947fffdf92c1dfad

在这里插入图片描述
每章一句感到累的时候,请抬头看看天空。感谢你能看到这里,点赞+关注+收藏+转发是对我最大的鼓励,咱们下期见!!!

标签:存储,进阶,32,浮点数,C语言,printf,pFloat,小数
From: https://blog.csdn.net/2401_83009236/article/details/142369726

相关文章

  • 20240909_181725 c语言 标识符
    什么是标识符命名规定标识符特性区分大小写命名约定演练小结......
  • C语言深入理解指针(四)
    目录字符指针变量数组指针变量数组指针变量是什么数组指针变量怎么初始化二维数组传参的本质函数指针变量函数指针变量的创建函数指针变量的使用代码typedef关键字函数指针数组转移表字符指针变量字符指针在之前我们有提到过,(字符)(指针)前面的字符代表着存储的元素为......
  • 数据飞轮:从静态存储到动态智能化营销的技术演进
    在如今这个数据驱动的商业时代,理解并运用最新的数据技术成为了企业逐鹿市场的重要武器。尤其是在全链路营销和智能推荐的业务场景中,从数据仓库到数据中台再到数据飞轮的发展历程,不仅展现了技术的革新,更是业务模式创新的体现。全链路营销的数据驱动转型在全链路营销领域,企业往往通......
  • 书生大模型实战(从入门到进阶)L0-Python
    目录Python实现WordCountVscode连接InternStudiodebugdebug单个python文件在vscode使用命令行进行debug本文是对书生大模型L0-Python部分的学习和实现,学习地址如下:学习地址:‬​​​​⁠​​‌⁠‍⁠​‬​​​​​​​⁠‬​​​⁠​​‌​​​​​‍​​​⁠​​​学......
  • c语言-数据类型
    1.C语言的简介  是一门面向过程的编程语言   1972年贝尔实验室 丹尼斯里奇   ...//百度百科https://baike.baidu.com/item/c%E8%AF%AD%E8%A8%80/105958?fr=ge_ala2.问题引入   1)我们所有要处理的这些数据文件(视频,音乐,图片等)    ......
  • C语言中if else组合
    一bool变量与“零值”进行比较bool变量与“零值”进行比较的if语句怎么写?boolbTestFlag=FALSE;//想想为什么一般初始化为FALSE比较好?A),if(bTestFlag==0);if(bTestFlag==1);B),if(bTestFlag==TRUE);if(bTestFlag==FLASE);C),if(bTestFlag);if(!bT......
  • 致态长江存储固态硬盘正常使用,突然损坏数据丢失修复
    当致态长江存储固态硬盘在正常使用过程中突然损坏导致数据丢失时,可以尝试以下几种修复和恢复方法:一、检查与初步诊断1.检查连接与电源:确保固态硬盘的连接线插紧,接口无松动或氧化。检查电源供应是否稳定,避免电源问题导致的损坏。2.使用系统工具检查:在Windows系统中,可以通过右击SSD驱......
  • C语言内容函数大揭秘:轻松掌握,编程无忧(下)
    大家们好,废话不多说,我们接着继续来讲我们函数的章节。六.数组做函数参数在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。比如:写一个函数将一个整型数组的内容,全部置为﹣1,再写一个函数打印数组的内容。1#include<stdio.h>23int......
  • 了解C语言
    1.什么是C语言C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目的是提供一种能以简易的方式编程,处理低级储存器,产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言是一门面向过程的计算机编程语言,C++,JAVA等面向对象的编程语言有所不同。......
  • 致态长江存储固态硬盘正常使用,突然损坏数据丢失修复
    当致态长江存储固态硬盘在正常使用过程中突然损坏导致数据丢失时,可以尝试以下几种修复和恢复方法:一、检查与初步诊断1.检查连接与电源:确保固态硬盘的连接线插紧,接口无松动或氧化。检查电源供应是否稳定,避免电源问题导致的损坏。2.使用系统工具检查:在Windows系统中,可以通过右......