目录
数据在计算机的存储方式(补码,反码,原码)
整形在内存中的存储:
整形类型
大端字节序和小端字节序
浮点数在内存的储存
在32位机器上,计算机储存数据是用32个比特位来储存数据,也就是32个0,其中第一位数为符号位,大多数情况用来表示整数是正的还是负的,我们先从原码说起,1和-1的原码分别为:
正数的反码不变,负数的反码在其原码的基础上符号位不变,其他位按位取反(0变成1,1变成0),即:
正数的补码还是不变,负数的补码在其反码的基础上加1:
所以我们可以总结:正数的原码,反码和补码都相同,而负数的原码,反码和补码在转换时才会不同,计算机在储存整形时用的都是补码。
我们知道C语言的整形类型有
我们知道char是字符类型,但是char类型储存字符的方式也是储存数字,然后在通过ascii码表转化为对应的字符,所以在这里我也将char当作是整形的一类了。
计算机会分配给不同类型不同的字节大小,也就是可以储存数字的大小:
对于不同整形无符号的问题,我拿char举个栗子
char类型的最大值和最小值在计算机的存储:
10000000~011111111 10000000为-128(这是计算机规定的),111111111为-127,011111111为127,
所以大小范围是-128到127
而无符号char类型,就是将最后一位符号位变成计算大小的位,即:
00000000~111111111=00000000~01111111+2^8,也就是0到255
在这里我们引入一下内存单元的概念,内存单元代表的是一个字节空间,即8个比特位,计算机会给这个内存空间分配一个地址(其实就是指针)。
当我们创建一个int变量,并且给他赋一个16进制的值 0x11223344,那么计算机会给他连续开辟4个字节大小的空间,他会有4个内存单元,接下来11将会被放在第一个内存单元,22放在第二个内存单元,下面也是一样,那么计算机会怎么给这些内存单元分配地址呢?于是就产生了大端字节序和小端字节序。
~两位16进制的范围大小等于8个比特位的范围大小
大端字节序存储:高字节序的内容放在低地址,低字节序的内容放在高地址
小端字节序存储:高字节序的内容放在高地址,低字节序的内容放在低地址
其中:高字节序代表高位数,即11,低字节序代表低位数,
我们可以测试下自己的编译器是大端的还是小端的,
#include<stdio.h> int main() { int a = 0x11223344; char* p = (char*)&a; printf("%0x", *p); return 0; }
如果运行的结果为44,则为小端,11为大端
根据国际标准,任意一个二进制浮点数都可以表示成:
(-1)^S*M*2^E
(-1)^s表示符号位,-1的s次幂要么是正数,要么是负数PM表示有效数字,M大于等于1,小于2;
2^E表示指数位。 -----总的来说就是二进制的科学计数法
浮点数在内存的存储其实就是S,M和E的存储
单精度浮点型float:最高的一位是符号位s,接着的8位是指数E,剩下的23位为有效数字M
其中,E的大小0~255
双精度浮点型double:最高的一位是符号位s,接着的11位是指数E,剩下的52位为有效数字M
其中E的大小0~2047
———————————————————————————————————————————
M的存储:
因为1<=M<2,所以M肯定为1.xxxxxxx,所以标准规定在计算机存储M的时候,不储存第一位数字1,当读取的时候才加上1,这样做的目的是节省一位有效数字,使计算机保存更多其他有效数字。
———————————————————————————————————————————
E的存储:
首先,E在计算机的存储肯定是一个无符号整形,这就意味着,当E为11位,那它的大小范围是0~2047,当E是8位时,它的大小范围为0~255
但是我们知道,在科学计数法表数的示时,它的指数位是可以取负,所以科学家为了使得E表示负数,在将E存储前加上一个中间数字,8位的E的中间数位127,11位的E为1023,这样在读取的时候给E减去这个中间数,在计算的时候E就能当作负数带来计算了。、
E的特殊情况
当E全位0的时候,那么E的真实值位1-127(或者1-1023),接下来在计算的时候M不会再加1,因为E为全0的时候算出来的数是无限接近于0的数,所以干脆就不给M加1,便于表示+0和-0;
当E全为1的时候,如果有效数字全为0,表示+无穷或者-无穷