目录
1.原码,反码,补码
2.整数再内存中的存储
3.大小端字节和字节序的判断
4.浮点数在内存中的存储
5.练习题
1.源码,反码,补码(正数的源码 反码 补码相同)
源码:将整数直接写成二进制的方式为源码
反码:除了符号位,其他的按位取反(1变成0,0变成1)即为反码
补码:反码加1即为补码
补码变源码:取反加1即可
所有的数据在内存中都是以二进制的方式存储的,对于整数,有源码,反码,补码的说法,而整数在内存中是以补码的,原因在于
:使用补码可以将符号域和数值域相互统一,同时减法和加法也可以统一处理(CPU中只有加法处理器,减去一个数等于加上一个数的相反数)
下面的图为详细讲解
如果用源码相加,得到的结果将会是错误的,看下图
2.整数再内存中的存储
大小端存储的由来:在算机系统中,是以字节为单位存储的,对于char类型的占8个比特为,即为1个字节,还有4个字节的,8个字节的,由与寄存器的宽度问题,自然就存在如何将数据的二进制存储,这样就产生了大端存储和小端存储
大端存储:数据的低位字节保存在内存中的高地址位,数据的低位字节保存在内存的高地址位
小端存储:数据的低位字节保存在内存的低地址位,高位字节保存在内存的高地址位
比如,对于下面的代码
#include<stdio.h>
int main()
{
int a=0x11223344;
return 0;
}
在vs编译器中,查看他的内存
a的低位字节保存在内存中的高地址处,所以为小端存储,
练习:如何使用代码判断编译器是大端储存还是小端储存
#include<stdio.h>
int main()
{
int a = 1;
int* pa = &a;
if (*(char*)pa == 1)
{
printf("小端");
}
else
{
printf("大端");
}
return 0;
}
4.浮点数在内存中的存储
国际标准认定,任何的浮点数都可以写成下面的形式
(-1)^s *M* 2^E
s为0 1,为0时表示为正数,为1时表示为负数
M为数值部分,取值的范围为介于1到2之间
E:取值为正整数
比如:-5.0 写成上面的形式为-1.01*2^2,其中,S=1,M=1.01,E=2,
对于浮点数
对于32位,第1位存的时符号位s,后面的8位存的是指数E,剩下的23位存的是有效数字M,
对于64位,第一位存的是s,后面的11位存的是指数E,剩下的52位存的是有效数字M,
其他的一些规定:
对于M,他总是可以写成1.xxxxxxxxx的形式,但是对于所有的数字,都有前面的数字1,所以在进行存储的时候,只是存小数点后面的数字xxxxxxxxxx,在取出来的时候,再把1加上去,比如5的M部分,可以写成1.01,就存01
对于E
先来探讨一些值的取值范围
signed char(有符号的字符型)
unsigned char(无符号字符型)
对于E,首先E是一个无符号整数,如果是8位的,他的取值范围就是0到255,对于11位的话,就是0到2047,但是结合前面的,E可能出现负数,所以,在E存在内存中的时候,就需要加上一个中间值,对于8位的,加上127,对于11位的,加上1023
举个例子
对于E的取出来分为三种情况
第一种
E不全为1或不全为0:E部分减去127或1023,M部分在前面添加一个1,使之变成1.xxxxxxx的形式
比如
对于上面的5.5,其二进制形式是
0 10000001 0110000000000000000000,第三部分的前面添加一个1,变成1.011000000000000000,第第二部分的10000001值为129,129只需减去127变成2即可还原,
第二种
E全为0,有效数字M前面加上一个0,使之变成0.xxxxxxx的形式,这样做是为了表示接近0的数字,
第三种
E全为1?
这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);?
0 11111111 00010000000000000000000
5.习题