【C语言】浮点型的存储方式

目录

一、浮点型和整型存储方式一样吗?

二、浮点型的存储规则

2.1  S,M,E求法

2.2 如何存放S,M,E 

2.2.1 IEEE 754规定

2.2.2 特别的规定

2.2.3  验证

2.3 取出规则

2.3.1 E不全为0或不全为1

2.3.2 E为全0

2.3.3 E为全1

2.3.4验证

END.


一、浮点型和整型存储方式一样吗?

尝试着做一下,看答案是否和你想得相同,如果不一样,那你算是找对文章了。

答案1:是以整型的方式存储,以整型的方式取出

答案2:是以整型的方式存储,以浮点型的方式取出

答案3:是以浮点型的方式存储,以整型的方式取出

答案4:是以浮点型的方式存储,以浮点型的方式取出

由此我们可以得知,整型的存储方式和浮点型的存储方式是不一样的

二、浮点型的存储规则

2.1  S,M,E求法

根据国际标准IEEE 754,任何一个二进制的浮点数都能表示为以下方式

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

浮点数为正数时S=0,反之S=1

M表示有效数字,在1~2之间(二进制)

2^E表示指数位

用一个实例来帮助大家理解

写出5.5对应的式子

5.5的二进制:101.1(小数点右边是从2的-1次方开始)

S=0(5.5为正数)

E=2(转换成科学计数法:1.011小数点左移两位)

M=1.011

既然浮点型可以用SEM来表示,那我们存放这三个值是不是就间接的把数据存在内存中了

所以在内存中存放浮点型就是在存放SME

2.2 如何存放S,M,E 

2.2.1 IEEE 754规定

 

2.2.2 特别的规定

存储M

在我们取M时会将它转换为1.xxxxxxxx(范围在1~2之间的数),如此我们存储时会一直存放一个不变的数1

IEEE 754规定:在计算机保存M时,默认他的第一位永远是1,因此可以将它舍去,只存储小数点后的数据,这样还可以提高精度

存储E

当我们在内存中存储E时,是从第二位开始的,没有符号位,所以它是一个无符号整数

当它占8位时(float)数据范围0~255,占11位时(double)数据范围0~2047

但是,我们在实际计算中E是可能出现负数的比如0.5

0.5的二进制:0.1

S:0

M:1.0(科学计数法的形式,小数点向右移1位)

E:-1

当E出现负数,但内存中不能表示负数,因为他是无符号类型

IEEE 754规定:再存入真实的E之前要加一个中间数,8位时加127,11位时加1023,如此就可以解决出现负数的情况

2.2.3  验证

我们进行一个简单的验证,同时让大家的记忆更加深刻

如果你在困惑内存中存放的为什么是倒过来的

这涉及到大小端的问题,在上一篇整型数据的存储时详细的讲解了这个问题,在此就不过多赘述

【C语言】整型的存储方式(大小端,原码,反码,补码)

2.3 取出规则

2.3.1 E不全为0或不全为1

S:存的什么就取出什么

E:当E的范围是8位时(float),存的时候+127,取得时候-127,得到的就是真实值

      当E的范围是11位时(double),存的时候+1023,取得时候-1023,得到的就是真实值

 M:存的时候,只存了小数点右边的值,取出来的时候要在前面加上1

2.3.2 E为全0

S:存的什么就取出什么

E:直接用1-127(1-1023)就为真实值

M:不用在加前面的1,直接是0.xxxxxxx

2.3.3 E为全1

存放的是无穷大的数字,存取规则和第一种情况相同。

2.3.4验证

// 这个是上面5.5存进去的列子
// 0 10000001 01100000000000000000000
// S    E          M
// S =0 是正数
// E = (10000001)129 - 127 = 2
// M = 0.011+1 =1.011
// (-1)^S*M*2^E
// 由此可以写出对应的数字

了解了怎样存储和取出浮点型数据,开头的那道程序是否有了不一样的见解

 

答案1和答案4

他们就是整型的方式存储,整型的方式取出,浮点型的方式存储,浮点型的方式取出

这里解析答案2和答案3

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	//整型方式存进去的是补码
	//00000000000000000000000000001001		//9的原码,正数的原反补相同
	//浮点型的方式取出,就认为里面存的是浮点类型,要用浮点型的规则取出
	//0 00000000 00000000000000000001001	
	//S    E          M
	//S = 0
	//E = 1-127 = -126
	//M = 0.00000000000000000001001	
	//(-1)*0*0.00000000000000000001001	*2^-128
	//是一个非常小的数字接近于0,float精度不够,所以只能打印出0.000000
	printf("*pFloat的值为:%f\n", *pFloat);

	*pFloat = 9.0;
	//浮点型的方式存进去,整型的方式取出来
	//9的二进制:1001		
	// S = 0
	// E = 3 +127 =130
	// M = 1.001
	//实际在内存中存储的是
	//0 10000010 00100000000000000000000
	//用整型的方式取出,就认为存进去的是补码(正数,原反补相同)
	//01000001000100000000000000000000 (原码)
	//原码换算成十进制为:1,091,567,616
	printf("num的值为:%d\n", n);
	return 0;
}

 

END.

有没有一种豁然开朗的感觉呢?有没有感觉到,生硬的规则下又透露出一丝丝的合理,让我对前辈们又多了一份敬佩。

如果对整型的存储有不清楚的地方,可以翻看我的另一篇文章.

【C语言】整型的存储方式(大小端,原码,反码,补码)

最后送给大家一句名言:

Genius only means hard-working all one's life. ——Mendeleyev  Russian chemist

天才只意味着终身不懈地努力。——俄国化学家 门捷列耶夫

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值