(c语言)数据存储————浮点型在内存中的存储

文章详细解释了整型数据在内存中以补码形式存储,正负数的表示方式,并对比了浮点型(单精度)数据的存储结构,包括符号位、指数位和尾数的表示方法。通过实例展示了浮点数如何转换为二进制并在内存中存储,以及不同类型数据间的转换可能导致的不同结果。
摘要由CSDN通过智能技术生成

整型在内存中的存储情况

通过学习,我们知道,整型数据在内存中存入的是该数据二进制的补码

对于正整数而言原码、反码、补码相同;

对于负整数而言 反码==原码按位取反、补码==反码+1;

例如:

正整数:

	int a = 20;

20的原码为:00000000 00000000 00000000 00010100

负整数:

	int b = -20;

-20的原码为:10000000 00000000 00000000 00010100

         反码为:11111111 11111111 11111111 11101011

         补码为:11111111 11111111 11111111 11101100

整型数据的第一位数据是用来存放符号位的

1为负数;0为正数

 整型有32个bit,1位为符号位;其余都是有效位;

那么浮点型呢?

我们通过几行代码测试一下;

	int a = 20;
	printf("%d\n", a);

	float* b = (float*)&a;
	printf("%f\n", *b);

	*b = 9.0f;
	printf("%d\n", a);
	printf("%f\n", *b);

首先将我们的变量a放入一个浮点型指针中,然后再利用解引用操作符打印出来,来对比相同数值,但不同类型的数据;

发现,数值根本就不相同

再通过解引用操作符修改a中的值为9.0的浮点型数据;

 修改后的两组数据根本就是天壤之别;

那么为什么会出现这种情况呢?

原因就在于:浮点型数据整型数据在内存中的存储情况是不同的

那么两者之间又有什么区别呢?

它又是如何表示的呢?

现在,就由我来讲解一下:

浮点型在内存中的的存储情况(本次介绍的是float(单精度浮点型)):

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

其中各个变量的含义如下:

  • S符号位,取值 0 或 1,决定一个数字的符号,0 表示正,1 表示负
  • M尾数,用小数表示,例如前面所看到的 8.345 * 10^0,8.345 就是尾数
  • E指数,用整数表示,例如前面看到的 10^-1,-1 即是指数

但我们知道数据在内存中存放的是一个个二进制序列,所以

尾数表示就变为了1.xxxxxxx,二进制表示中不会出现除0、1之外的数字

指数位也有所不同;因为它是二进制的缘故所以就表示为2^x;x是指数

用图像表示    float(单精度浮点数):

 并且这三块区域都有不同的存法和取法;

符号位S:0表示为正数;1表示为负数,对应表达式(-1)^S

指数位E(E不全为0和E不全为1):指数位中规定存储进去的是unsigned int 类型(无符号整型);单精度浮点数有8个bit来存放E;所以E的取值范围就是0~2^8-1(0~255);缘于它有点庞大的取值范围;在存入的时候规定指数的真实值要加上一个中间值再存入;float(+127) double(+1023);取出的时候再减去这个中间值就可以了。

尾数部分M:我们知道;十进制的数字用科学计数法表示就是:x.xxxx*10^x;那么浮点数就表示为:1.xxxx*2^x;又因为二进制中如果用科学计数法表示的话,那么就都会写成1.xxxxx这样的数字;尾数部分就规定,在存入尾数位时舍去小数前面的1,只存后面的小数部分,这样做,就不会因为多存那个1而降低精度,也不会影响数值,取出的时候再加上那个1就没什么问题了。

E的另外两种情况

E为全0:在读取内存中的浮点型数据时,如果指数位为全0时;思考一下;此时的E是在加上了中间值(float+127)(double+1023)的数值;那么E的真实值就是0-127=-127;若一个数字写成±1*1.xxxx*2^-127的形式,它就是一个无限接近于0的数值;所以规定若某个浮点型在内存中存入的E为全0时,指数位统一表示为1-127=-126。

E为全1:指数位为全1时;说明它在存入时加上了中间值后为全1;真实值还原等于255-127=128;若一个数表示成±1.xxx*2^128的形式,那么它就是一个正负无穷大的数值。

介绍了这么多;不妨举个例子,说明一下;

举列子说明(5.5)

比如:5.5它是怎么存入内存当中的

一步一步的将5.5拆解,存入不同的区域当中

5.5用二进制表示为:101.1

记为:1.011*2^2

5.5为正数

符号位为:0

指数位2+127 为 129:10000001

小数位丢弃1.011中小数前的1 为:01100000000000000000000

综合下来,5.5存入到内存中的二进制序列为:0 10000001 01100000000000000000000

内存中的表示为:00 00 b0 40(小端机器下的内存显示)

 回归到开头的那几行代码:

	int a = 20;
	printf("%d\n", a);

	float* b = (float*)&a;
	printf("%f\n", *b);

	*b = 9.0f;
	printf("%d\n", a);
	printf("%f\n", *b);

现在通过一步步介绍,我们了解到整型和浮点型存入内存的存储方式不同,那么如果硬要以浮点型的方式打印整型数据和以整型方式打印浮点型数据,就会以不同类型的存储方式,读取内存中的值,打印出不同的结果;

20的二进制序列:00000000 00000000 00000000 00010100

若以浮点型的形式打印

内存中读取时就会将整型的二进制序列划分区域

:0 00000000 0000000 00000000 00010100

此时表示的就是一个0.000000这样的数字;

将浮点型9.0的数据存入再以整型方式打印时

9.0表示为 :1.001*2^3

内存中的表示情况为:0 10000010 00100000000000000000000

以整型存储方式读取时合并三块区域

:01000001000100000000000000000000

打印出的数值为:1091567616

 希望本次的介绍能够对你有所帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值