原码、反码、补码概念及转换

文章目录

      • 基础概念
        • 原码
        • 反码
        • 补码
      • 三种编码方式存在的原因

基础概念

  • 数据在计算机内部是以补码的形式存储
  • 数据分为有符号数和无符号数
    • 无符号数为正数,有符号数为负数,计算机内部是以补码的形式存储的
    • 正数的首位地址为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

你可能感兴趣的:(c语言)