在计算机当中通常以8位的块或者字节(byte)作为最小的可寻址内存单位
- 一字节由8位组成,在二进制表示法中它的值域为00000000 ~ 11111111
- 看成十进制数则是0~255,由于二进制位太冗长而十进制与位模式的转换麻烦,则出现了以16为基数,称作16进制数,有'A' ~ 'F' 对应 ‘10’ ~ ‘15’,0~9则不变,1byte则为FF
- 对于c语言而已由0x开头的数字常量常被认为十六进制数,如0xF53BAC4之类都为十六进制。
进制之间的转换
- 对于二进制转十进制则为按权展开,设有一位向量集合其中有位,按照形式相加即可。
- 而对于二进制而言,每四位作为一组以转转十进制形式,不够位则补0,最终联合即可得到十六进制,十六转二也为此形式,反过来十进制转十六进制可十六取余从下往上组合即可,十六进制和八进制转十进制分别为以16和8为底的幂即可。
- 例如,376十进制转十六进制结果为(178),其余转换都可以按位的模式权的幂进行转换
- 当某一个十进制x=,则可以按照n=j + 4*i形式快速转换十六进制,其中0<= j<=3,则当0x开头后十六进制首位开始:1(j=0)、2(j=1)、4(j=2)、8(j=3),后面紧跟i个0。例如
- 进制转换作为基础就到此结束
0
0 1 1 1 1 1 1
接下来正式进入计算机中位的存储规则
- 首先在计算机虚拟地址中每个空间都有字节的编号,由低位地址到高位地址布局
- 由此可知存储分为大端存储及小端存储,前者为高位在高位低位在低位,后者则相反,由此则清楚由计算机的存储规则不同,有些编译器小端字节序要么大端字节序,接下来让我们来看看vs编译器上c语言存储序列方式
- 很明显,这里采用的是小端存储方式,由此我们可以简单的设计一个按字节序输出的小程序,如下
#define byte_pointer unsigned char* void show_byte(byte_pointer start, int size) { int size_f = 0; for (size_f; size_f < size; size_f++) { printf("%x\n", start[size_f]); } } void show_int(int x) { show_byte((byte_pointer)&x, sizeof(int)); } void show_float(float x) { show_byte((byte_pointer)&x, sizeof(float)); } int main() { show_int(0x32455); return 0; }
- 以上便是通过指针确定其地址且强制转换为char*类型,因此任何数据类型便可以按字节序输出(无符号数)。
各种数据类型的编码格式及之间的转换关系
- 无符号数就不过多概述,按照正常算术逻辑计算即可,即没有符号位都为实数
- 反码:源码按位取反即可
- 补码:一般为负数,补码则在反码基础上加一即可
- 补码转无符号数:右图所示为其公式,x为某十进制数,仅当x无溢出在位数最大值最小值内
无符号转补码:减去最高位2的总位数次即可,负数情况下不变 下面我们就来看以下浮点型的表示
- 首先二进制小数特性:左移n位则此数乘以2的n次幂等于原值,最终的十进制数
- 因此由此方式也可从十进制转二进制,小数位最大值为分母最大值,分子比父母少一,如0.1111,后有4位连续二进制1则十进制值为2的4次方分之2的四次方减一。
- 接下来是IEEE浮点数表示法:采用科学计数法方式存储
- 以下为其float与double的位数划分
- 情况1:规格划的值 :在该情况下E=e-Bias,其中bias为偏置值等于 其中k为其阶码位的总位数(单精度127,双精度1023),在此情况下M=1+f(尾数) 即隐含1。
- 情况2:非规格化时偏置值为,也不存在隐含的1,其余计算方法都 类似。
- 情况3:当阶码字段全为1时,小数域全为0时得到的结果为无穷,s=0时为正无穷,s=1时为负无穷。
- 接下来举个例子如下
- 上图为实际存储,VS编译器默认为小端存储
- 以上便为基本数据存储的基础