1、整型在内存中的存储
1.1、整型大家族
short 短整型
int 整型
long 长整型
long long 更长的整型
1.2、有符号类型和无符号类型
unsigned (无符号类型)
声明格式:unsigned int a; 这时a就是一个无符号的int 类型数据
含义:
就是指没有符号位(用来表示正负的二进制位),只能表示整正数,所以unsigned int类型所能表示的范围是0~2^32-1(int的大小为4个字节及32个二进制位)
signed (有符号类型)
声明格式:signed int a;
与无符号不同,有符号类型的数据需要用一个二进制位来表示实在正负
signed int 型的 1
signed int 型的 -1
如果不写unsigned 和signed,直接 int a; 一般编译器会将其默认为 signed int a; (其他整形也是同理)
需要注意以下几点:
1、符号位为1其余位为0时,该数据表示
例:signed short 1000 0000 0000 0000 表示-2^15
signed int 1000 0000 0000 0000 0000 0000 0000 0000 表示-2^31
将其当作规定就行,不用深究,所以signed int的数据范围是-2^31 ~ 2^31-1
2、字符类型char也可以用unsigned 和signed声明。
1.3、原码反码补码(仅应用于有符号类型)
整型在内存中储存的都是补码(还有char),正数的原码、反码、补码完全相同,原码就是1.2里面的哪些数据的表示,比如
对于 short类型(为什么用short了,因为短呀!)
0000 0000 0000 0001 1的原码
0000 0000 0000 0001 1的反码
0000 0000 0000 0001 1的补码 (内存存储)
但是负数
对于 short类型
1000 0000 0000 0001 -1的原码
1111 1111 1111 1110 -1的反码 (符号位不变其余位取反)
1111 1111 1111 1111 -1的补码 (在反码上加一)(内存中的形式)
1.4、*为什么要引入原码反码补码
因为cpu只能进行加法运算,而我们存储的是补码
当我们使用正数的补码与负数的补码相加是,刚好得到的是结果数的补码,但用原码相加却无法达到。
还是用short来演示
1000 0000 0000 0001 -1的原码
加上
0000 0000 0000 0001 1的原码
得
1000 0000 0000 0010 从原码来看读作-2
而补码
1111 1111 1111 1111 -1的补码
加上
0000 0000 0000 0001 1的补码
得
1 0000 0000 0000 0000
超过了short的大小舍去超出的部分得(为什么从高位舍?规则嘛)
0000 0000 0000 0000 就是0
还是不懂可以看看大佬的这篇:
(3条消息) 计算机为什么要使用原码、反码、补码_藏红的博客-CSDN博客_为什么还要通过原码、反码的方式求补码呢
2、浮点型在内存中的存储
根据IEEE 754 标准,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
表现在内存中主要分为这样三个部分
对于32位的float,这么分(注意顺序)
对于64位的double,这么分
举个例子(顺序顺序!)
5.5=101.1(二进制)
=1.011 * 2^2(二进制科学计数法)
=(-1)*0 *1.011 * 2^2
S M E
2.1、符号位S
表示整个浮点数的正负
2.3、尾数位M
存放浮点数的尾数部分。开头的1省去不记。
比如1.011这么存,因为科学计数法第一位肯定是1,这样可以节省一个bit位
2.2、指数位E
浮点数的指数部分(二进制科学记数法的指数)。指数也有正负,使用移位存储来表示正负。(不是符号位)
移位存储(移码):将每个数 + 偏置值(值=2^(k-1) -1)作为最终结果存储。
比如float有八个位共能表示2^(8-1)-1==127
然后 存储2时
所以5.5在float型的存储形式为