一、原码、反码和补码
1.存储位长与机器位长
首先我们要了解一下比特位和字节。比特位是计算机中最小的信息单位,我们可以通过不同的比特位组合来表达不同的数据信息。字节是更高一级的单位,1个字节等于8个比特位。
- 存储位长: 我们的存储器一般有8位、16位、32位、64位等,这些指的就是存储位长,它代表存储器中的每一个存储单元可以存放的数据的长度。
- 机器位长: 机器位长指的就是CPU一次能够处理的数据的长度,其实也就是寄存器能保存的数据的位数。
2.原码、反码和补码的计算
计算机中的数据存储都是以二进制进行存储的。在计算机中存储整数的方式有三种,分别是原码、反码和补码。这三种表示方法都由符号位和数值位两部分组成,最高位表示符号位,二进制0表示正数,二进制1表示负数。原码、反码和补码的计算方法分别如下:
- 原码: 直接将数值按照正负数的形式翻译成二进制就可以得到原码。
- 反码: 将原码的符号位不变,其它位依次按位取反就可以得到反码。
- 补码: 反码+1就可以得到补码
下面我们举个例子来演示一下,假设我们要将整数-15分别转换成原码、反码和补码(在32位机器下运算):
事实上整数在内存中是以补码的形式存储的。原因是计算机中只有加法器,它其实是不能够直接算减法的。比如说我们要算1-1的值,在计算机中会转换成计算1+(-1)的值,也就是将减法转换成加法来计算。那么我们可以尝试一下,如果使用原码来计算,最后算出来的结果不是正确的,只有使用补码来计算,最后算出来的结果才是正确的。
二、大小端字节序
大小端字节序指的是数据在内存中的存储顺序。
- 大端字节序: 当一个数据的低字节数据存放在高地址处,高字节数据存放在低地址处,这种存储方式就是大端字节序。
- 小端字节序: 当一个数据的低字节数据存放在低地址处,高字节数据存放在高地址处,这种存储方式就是小端字节序。
下面我们可以举一个例子来说明一下大小端字节序,假设整数用16进制表示为0X11223344,那么它在内存中的大端字节序存储和小端字节序存储分别如下图所示:
我们可以写代码来测试一下我们的计算机是大端字节序存储还是小端字节序存储,代码的逻辑是:数据在计算机中存储是以字节为单位的,我们只需要取出数据首位字节的数据进行对比即可判断是大端字节序存储还是小端字节序存储。
#include <stdio.h>
// 判断大小端字节序
int check_sys()
{
int i = 1;
// i是整数,我们只需要取它首位的一个字节
// 所以强制类型转换成char*返回即可
return *(char*)&i;
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端字节序\n");
}
if (ret == 0)
{
printf("大端字节序\n");
}
return 0;
}
运行程序查看结果:我们的机器是属于小端字节序的。