1. 补码

Two's Complement(二补数、补码)是对二进制数的数学运算,运算过程为:对二进制序列每一位取反(0->1; 1->0),再加1。

bits 取反 补码
011 100 101
010 101 110
111 000 001

2. 计算机中有符号数的表示

计算机中的数值类型分为整数型和浮点数型,有符号数在最高位设置符号位,其余低位均为数值位。数值位一律采用补码形式存储,并参与计算。采用补码的形式表示有符号数至少有两大好处。

  • 符号位和数值位统一参与运算,不用区分正、负,加法和减法实现简单;
  • 数据的原码和补码之间的相互转换不需要依赖额外硬件电路。

下面分别介绍有符号数的表示方法

2.1 整数

正整数

正整数的补码是其二进制表示,与原码相同。
例如,在整数类型占用4字节(32位)的系统中,+5的补码是00000000 00000000 00000000 00000101。最高位0表示该数值为正数,其余31位表示数值大小。

负整数

负整数的补码需要对其绝对值的二进制表示进行补码运算。
例如,-5的补码是11111111 11111111 11111111 11111011。最高位为1,表示该数值为负数,其余31位表示数值大小。

在进行运算时,CPU并不会区分是正数还是负数,而是直接进行计算,这正是前面介绍的符号位和数值位的统一。
例如,a=10, b=-5,则a+b的运算过程如下:

  00000000 00000000 00000000 00001010 (10)
+ 11111111 11111111 11111111 11111011 (-5)
===========================================00000000 00000000 00000000 00000101 (5)

如果,a=1, b=5,则a-b首先转换成加法a+(-b),再进行计算,过程如下:

a-b ==> a+(-b)00000000 00000000 00000000 00000001 (1)
+ 11111111 11111111 11111111 11110110 (-10)
===========================================11111111 11111111 11111111 11110111 (-9)

对于正整数(最高位为1),将非符号位的二进制位直接转换成十进制,就表示该正数的实际大小。如果一个数是负整数,如何将其补码转换成十进制大小呢?补码运算即可。
例如上面的11111111 11111111 11111111 11110111,最高位符号位是1,所以该数为负数,补码运算之后为00000000 00000000 00000000 00001001,大小为9,所以表示-9

2.2 浮点数

pass

3. 为什么是补码?

为什么两个数相减a-b用补码形式a+(-b)进行计算的结果是正确的?不妨看一下对b进行补码的过程绝对值的二进制序列取反,再加1。取反在计算机的逻辑电路中就是开关的闭合状态取反即可,即1->0,0->1。如果用数学算式表达的话,对一个bit位b的取反运算可以写成

取反b = 1-b (*)
b=0时,取反b为1,1-b=1;
b=1时,取反b为0,1-b=0;
所以算是(*)可以表达取反运算

综上,a-b的计算过程可表达为(8bit为例)

a-b == a+(-b) == a+(11111111-b+1) == a+(b的补码形式)
在8bit系统中,11111111 + 1 == 00000000,溢出。
所以,a+(11111111-b+1) = a+(0-b) = a - b

可以看出,补码运算的实现效果巧妙地利用了因计算机系统位数限制而产生的溢出现象。

4. 一个C++面试题

下面代码打印多少?

#include <iostream>

int main(int argc, char **argv)
{
std::cout << 25u - 50;
return 0;
}

答案是4294967271

25uunsigned int类型,50为int类型。在这两种操作数进行-运算时,int被提升为unsigned int型,运算变为25u - 50u,结果也应该是unsigned int类型。经过对-50u进行补码运算后带入加法运算,-25的二进制表示形式被存入内存,即11111111 11111111 11111111 11100111(int为32位),在打印时按无符号数处理,则直接转换成十进制正整数为4294967271

11111111 11111111 11111111 11100111 =
2^31 + 2^30 + ... + 2^5 + 2^2 + 2^1 + 2^0 =
2^5(1-2^27) / (1-2) + 7 =
4294967271

补码、无符号数减法运算相关推荐

  1. 信息存储 整数表示 原码 反码 补码 无符号数 有符号数 转换 扩展 截断

    虚拟内存,地址,虚拟地址空间 程序对象:程序数据.指令和控制信息 16进制 字数据大小 字长 寻址和字节顺序 最小的地址 小端法和大端法 字符串表示 ascii unicode 代码表示 布尔代数 c ...

  2. C语言位运算之有符号数和无符号数

    相同长度数据类型位运算 #include<stdio.h> int main(int argc, int* argv[]){int a_int1 = 0xFFFFFFFF; //有符号数负 ...

  3. 补码还原为原码c语言,C语言知识汇总 | 12-整数(有、无符号数)在内存中的存储——原码、反码与补码...

    加法和减法是计算机中最基本的运算,计算机时时刻刻都离不开它们,所以它们由硬件直接支持.为了提高加减法的运算效率,硬件电路要设计得尽量简单. 对于有符号数,内存要区分符号位和数值位,对于人脑来说,很容易 ...

  4. 计算机中的无符号有几种,【数据结构】整数类型之有符号、无符号数(原码、反码、补码)详解。...

    Fist:why? 有时候只知道什么还不够,我们还需要为什么,所以我在整个数据结构系列中都要追寻这个答案. Q1:为什么需要整型数据. 因为整型数据结构跟生活密切相关,生活中.数学中到处都是整型数字. ...

  5. 有符号数和无符号数详解(2)补码详解

    有符号数和无符号数详解(2)补码详解 1. 为什么需要补码 1.1 背景 2 补码的思想 2.1 我们希望只设计加法运算器,不用减法运算器. 2.2 现在问题是:怎么表示-1呢? 3. 补码 3.1 ...

  6. 无符号数、有符号数、补码在汇编中的运用及相关注意事项

    1.原码.反码.补码知识的复习: 三者的最高位均为符号位.我以前一直没弄明白的是为何8位补码的表示范围是-128~127,今天查阅了相关资料,于此记下. 仍然以8位为例: 原码的表示范围:-127~- ...

  7. 笔记:扩展一个数字的位表示 无符号数的零扩展 补码数的符号扩展

    一.无符号数的零扩展 如果是无符号数,想要扩展n位 则是在前面添加n位0 二.补码数的符号扩展 如果是补码数,想要扩展n位 看最高位是0还是1,是0则扩展0,是1则扩展1. 如果想要扩展2位,如下例: ...

  8. 有符号数与无符号数比较-详解

    正如我们所知道的,编程语句都有很多的基本数据类型,如char,inf,float等等,而在C和C++中还有一个特殊的类型就是无符号数,它由unsigned修饰,如unsigned int等.大家有没想 ...

  9. 有符号数、无符号数理解

    大家都知道,在C/C++中,对于w位编译器,其有符号数表示的数值范围为-2 ^ (w-1)~2 ^(w-1)-1,无符号数表示的数值范围为0 ~ 2 ^ w-1,举个例子,在16位编译器中,有符号数的 ...

最新文章

  1. UVa11107 - Life Forms(后缀数组)
  2. 2020年 第11届 蓝桥杯 Java B组 省赛真题详解及小结【第1场省赛 2020.7.5】
  3. 运动会成绩管理java代码_基于jsp的运动会成绩管理-JavaEE实现运动会成绩管理 - java项目源码...
  4. react当中子组件改变父组件的状态
  5. 【计算机算法设计与分析】——排序
  6. Java 流式编程stream
  7. 【五】每个球队胜率统计
  8. python qt 拖拽组件使用方法_Python QT组件库qtwidgets的使用
  9. 多元线性回归模型-数学建模类-matlab详解
  10. vsftpd 启动不了vsftp 报错:config file not owned by correct useror not a file
  11. 换SSD硬盘,重装系统,一阵子忙乱
  12. vivoz3android版本多少,谁更值得买—荣耀V10 OR vivo Z3
  13. LINUX也有C#?
  14. stata 空间杜宾模型_一文读懂空间计量及stata应用(二)(附lr检验、动态空间面板杜宾/滞后模型dofile等)...
  15. python判断题题库大数据技术_智慧树_大数据分析的python基础_判断题答案
  16. c#删除sheet_C#中实现插入、删除Excel分页符的方法
  17. 查询计算机ip地址的方法,计算机的ip地址查询的几种简单方法介绍
  18. ecap捕捉epwm波形的占空比及频率(总结)
  19. 推荐免费下载华软源码430套大型企业管理源码,下载地址:http://www.hur.cn/tg/linkin.asp?linkid=205389 源码语言:PB/Delphi/VB/Java/.Ne
  20. 怎么把几个pdf合并成一个文件?这个pdf合并的方法不容错过

热门文章

  1. android学习总结
  2. java 子线程退出_java – 在子线程完成执行之前主线程将退出吗?
  3. 百度熊掌推送php源码,织梦百度熊掌主动推送教程
  4. linux编写运行shell程序,Linux的Shell编程运行Shell程序的方法有哪些呢?
  5. dbscan论文_论文分享 :Linkage Based Face Clustering via GCN
  6. python表情识别程序_Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
  7. Knapsack Cryptosystem(2019牛客多校折半查询)
  8. java不用析构函数,堆栈分配的类--C发生不需要的析构函数调用
  9. 【算法竞赛学习】气象海洋预测-Task4 模型建立之 TCNN+RNN
  10. java mybatis 代码生成器_Java MyBatis-Plus 代码生成器