整数和浮点数在内存中存储的


在这里插入图片描述

整数在内存中的存储

整数的2进制表示法有三种:原码、反码和补码。
三种表⽰⽅法均有符号位和数值位两部分,符号位⽤0表⽰“正”,⽤1表⽰“负”,而数值位最⾼位的⼀位是被当做符号位,剩余的都是数值位。

int a = 1;

0 0000000 00000000 00000000 00000001
| —————————————————————————————————— 
|                数值位
符号位

在计算机存储数据时,是存数据的补码。
正数的 原码,反码,补码都相同。
负数的 原码,反码,补码都不相同。

原码:就直接将数值转换成二进制数的形式
反码:在原码的基础上取反,符号位不变
补码:在反码的基础上加 1

技巧:补码————>原码
对补码 取反 再加1

-2原码
10000000 00000000 00000000 00000010
反码
11111111 111111111 11111111 11111101
补码
11111111 111111111 11111111 11111110
------------------------------------
补码————>原码
1.取反 
10000000 00000000 00000000 00000001
2.1
10000000 00000000 00000000 00000010

这样可以快速求出原码 (^ _ ^)

大小端知识

神马是大小端?
大小端就是内存存储二进制位顺序的方式
小端:低地址存低数据
大端:高地址存低数据

int a = 1;
00000000 00000000 00000000 00000001 
						      ———— 
						     低数据位
假设:地址由低 -------> 高
——————————————————————————————————————————>
 小端:00000001 00000000 00000000 00000000 
 
 大端:00000000 00000000 00000000 00000001 
 

看一下VS2022采用的是小端存储
在这里插入图片描述

同志们思考一下,写个程序怎么判断大小端呢?

浮点数在内存中的存储

浮点数的存储可比整数的存储要复杂的多了!!!
首先看一段代码,引出浮点数的存储与整数的存储是不同的!!!


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

	*fP = 9.0;
	printf("*fP = 9.0后,n的值为:%d\n", n);
	printf("*fP的值为:%f\n", *fP);
	
	return 0;
}

思考一下输出结果
n 一看是9
*fP 也是9吗?
*fP = 9.0后, n的值还为9吗?
*fP 一看也是9
那最终结果是???????
在这里插入图片描述
斯~ ~ ~ ~,和我们一开始想的不一样。这也就证明了一开始的浮点数的存储与整数的存储是不同的

那有什么不同呢?就跟着小编 ^ — ^ 往下面看。

根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
V = ( − 1 ) S ∗ M ∗ 2 E V = (−1)^S* M ∗ 2^E V=(1)SM2E
• (−1)^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
• M 表⽰有效数字,M 属于 [1,2)
• 2^E 表⽰指数位

⼗进制的5.0,写成⼆进制是 101.0 ,相当于 1.01 * 2^2 = (-1)^0 * 1.01 * 2^2
那么,按照上⾯V的计算公式,可以得出S=0,M=1.01,E=2。

IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

在这里插入图片描述

  • 如果E为8位,它的取值范围为0 ~ 255;如果E为11位,它的取值范围为0~2047。
00000000    11111111 = 2^8 - 1 = 256 - 1 = 255 

00000000000 11111111111 = 2^11 = 2048 - 1 = 2047
  • 但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

指数E在内存可以分成三种情况:

E全为0


x 00000000 xxxxxxxxxxxxxxxxxxxxxxx
_ ________ _______________________
|	 |				|
S    E				M
		

规定:

  • 浮点数的指数E等于1-127(或者1-1023)即为真实值
  • 有效数字M不再加上第⼀位的1,⽽是还原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。

E全为1


x 11111111 xxxxxxxxxxxxxxxxxxxxxxx
_ ________ _______________________
|	 |				|
S    E				M

  • 如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);

E不全为0或不全为1

就按之前的规则
⽐如:0.5 的⼆进制形式为0.1,由于规定正数部分必须为1,即将⼩数点右移1位,则为1.0*2^(-1),其
E 为-1+127(中间值)=126,表⽰为01111110,⽽尾数1.0去掉整数部分为0,补⻬0到23位
00000000000000000000000,则其⼆进制表⽰形式为:


0 01111110 00000000000000000000000
_ ________ _______________________
|	 |				|
S    E				M

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是无敌小恐龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值