文章目录
基础概念
- 数据在计算机内部是以补码的形式存储
- 数据分为有符号数和无符号数
- 无符号数为正数,有符号数为负数,计算机内部是以补码的形式存储的
- 正数的首位地址为0,其原码是由十进制数转换为二进制数
- 负数的首位地址为1,其原码是由十进制数转换为二进制数,然后将首位地址改为1
- 对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式,原码、反码、补码是计算机原理的术语。说白了就是为了理解计算机使用二进制进行运算的原理。对于C/C++来说,是和数据类型有关的
原码
原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值
正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010
注意: 二进制位的首位标识该二进制数是一个正数还是负数,正数为0,负数为1
反码
- 正数的反码 == 原码
- 负数的反码是在其原码的基础上,符号位(首位)不变,其余各个位取反
正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010
正数: 10 的反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的反码 --> 1111 1111 1111 1111 1111 1111 1111 0101
补码
- 正数的补码 == 原码
- 负数的补码是在其反码的基础上加1
正数: 10 的原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的原码 --> 1000 0000 0000 0000 0000 0000 0000 1010
正数: 10 的反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的反码 --> 1111 1111 1111 1111 1111 1111 1111 0101
正数: 10 的补码 --> 0000 0000 0000 0000 0000 0000 0000 1010
负数:-10 的补码 --> 1111 1111 1111 1111 1111 1111 1111 0110
三种编码方式存在的原因
计算机只会做加法计算
当两个正数之间使用原码进行运算就可以解决
// 由于计算机只会做加法运算,减法运算在计算机的表现形式为
10 + 1
使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
1 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 0001
两者相加 --> 0000 0000 0000 0000 0000 0000 0000 1011 // 该原码转成十进制为 11
当正数和负数使用原码运算的时候就会出现问题
// 由于计算机只会做加法运算,减法运算在计算机的表现形式为
10 - 1 == 10 + (-1) // 后者为计算机的表现形式
使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成原码 --> 1000 0000 0000 0000 0000 0000 0000 0001
两张相加 --> 1000 0000 0000 0000 0000 0000 0000 1011 // 该原码转成十进制为 -11
因为正数和负数之间使用原码运算会出现问题,为了解决这个问题,反码就出现了
// 使用反码进行计算
10 - 1 == 10 + (-1) // 后者为计算机的表现形式
使用原码进行计算如下:
10 转成原码 --> 0000 0000 0000 0000 0000 0000 0000 1010 --> 转成反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成原码 --> 1000 0000 0000 0000 0000 0000 0000 0001 --> 转成反码 --> 1111 1111 1111 1111 1111 1111 1111 1110
10 转成反码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成反码 --> 1111 1111 1111 1111 1111 1111 1111 1110
两者反码相加 --> 1 0000 0000 0000 0000 0000 0000 0000 1000 // 左侧超出的部分会被自动去掉,该原码转成十进制为 8
注意:反码在进行正数与负数之间的运算所得的值会相差1
由于反码在进行正数与负数之间的运算所得的值会相差1,为了解决这个问题,补码就出现了
10 转成补码 --> 0000 0000 0000 0000 0000 0000 0000 1010
-1 转成补码 --> 1111 1111 1111 1111 1111 1111 1111 1111
两者补码相加 --> 1 0000 0000 0000 0000 0000 0000 0000 1001 // 左侧超出的部分会被自动去掉,该原码转成十进制为 9