什么是Complement(补码)?

大学上过计算机原理课程的朋友都接触过补码这个概念,不过当时书上所教授的内容都是以二进制作为前提,即所谓的2的补码(2‘s Complement)。近来看TCP/IP Volume 1时,又接触到“1的补码”这个概念,忽然发现其实还不太明白补码到底是什么意思,故查阅资料记录之。

资料来源:维基百科

术语解释:Radix —— 基数,在本篇文章的范畴内等价于“进制”

定义:给出长度为n的数值y,则y的以基数b的补码为: bn - y   (即 b的补码)

水平有限,翻译的比较拗口,不过公式还是很简洁的,实际上补码从定义上来说并没有什么难懂的地方。不过有些地方需要加以说明,补码这个概念是建立在进制(即基数)的基础上的,至少在计算机科学的术语中,补码定义中的基数b是一定等于当前进制的,也就是说以上定义可以简化为

给出长度为n的数值y且该数值为b进制,则y的补码为: bn - y

下面以十进制的数作为例子

给出数值y = 1234,很明显长度n = 4,基数b = 10(你说不知道10从哪来的?论审题的重要性)

根据补码的定义那么 y的补码为:104 - 1234 = 8766

用途:补码的作用是什么呢?你走运啦,补码的用途很专一 —— 用加法操作来代替减法操作

听起来匪夷所思,你几乎要脱口而出:“不可能!!!”,不过按照国际惯例,我们先来看看到底怎么回事吧

这里要引入另一个很简单但是英文又很有bigger的术语: 缩小基数补码 (diminished radix complement),看到 diminished 这个词我立马打个激灵,想起了久未谋面的缩小增量排序(diminished increment sort),啥?你说老师没教过这个?噢,它的另一个名字叫希尔排序,它是。。。咳咳,不好意思跑题了。

缩小基数补码实际上就是 (bn - 1) - y,就是说你可以通过往缩小基数补码上加个 1 来得到基数补码,也就是说

bn - y = (bn - 1) - y + 1

是不是想大喊一声:这TM不是废话么??

这个概念有什么用?其实在纯数学的范畴内,这个纯属多余,没有任何用处。然而到了我这个年纪,就会明白一切看起来无意义的东西,肯定一定必须存在一个让它拥有意义的上下文环境。在本文内,这个环境就是“一个数值的长度”,你要知道在数学范围内,你想把一个数写多长就有多长,但是在计算机内数值长是固定的,譬如Java语言的int数值长度为32位,你无法用32位的数去表示33位数,当然34位就更不行了!

回到基数b这个关键字上面来,还是以十进制数为例子

假设数值长度为固定的4,给出数值y = 1234,如果说你真的要按照定义在计算机内去获得补码,你是做不到的,因为根据定义补码为104 - 1234,然而104  = 10000,已经超出了4位数所能表示的范围,你明白了么?缩小基数补码就是为了能在固定的数值长度中去获得补码,所以退一步海阔天空啊

  1. 104 - 1 = 9999
  2. 9999 - 1234 = 8765
  3. 8765 + 1 = 8766

然而,聪明如你一定发现了,说是补码的用途是用加法代替减法,可是在以上第二步获得补码的关键步骤里,不还是要进行减法??这有毛区别?哈,这个就是最让人兴奋的地方,在二进制世界里,你不需要再用减法了,下面以二进制为例子

给出数值y = 1011,那么很明显,按照最新的补码求解步骤,补码 = ( 24 - 1 ) - 1011 + 1,猛然一看,这哪里履行了补码的承诺,用加法代替减法?那么我们就以二进制的视角去看

y    =  1011

24 - 1   =  1111

实际上你已经发现了,这个缩小基数补码是固定的——给定计算机数值长度n,则缩小基数补码可以直接写出:pppp...ppp(n个p,p = 进制 - 1),而关键的

1111 - 1011,这一步实际上已经不需要作减法操作了,直接对 y 取反再加上 1 就能得到补码了(是不是对“取反加一”感到特别耳熟?你是个上课听课的好孩纸),在此不得不感谢伟大的二进制!需要再次声明下,这么流畅的操作只有二进制能完成,其他进制想要获得补码,依然需要减法。

终章:在神奇的二进制世界中,获得一个数的补码只需要简单的取反再加上一就可以了。那么最后我们来看看,补码到手之后,又怎么能代替减法呢?

假设需要求解 x - y ( x >= y),那么分为以下步骤

  1. 求得y的补码 bn - y
  2. x - y = x + ( bn - y ) = x  - y +  b (这一步用补码的加法代替了原数值的减法)
  3. 显然 x  - y +  bn >= bn,然而bn已经超出了数的表示范围(overflow),直接被丢弃了,最后的结果就等于x  - y
时间: 2024-12-22 16:15:19

什么是Complement(补码)?的相关文章

words2

餐具:coffee pot 咖啡壶coffee cup 咖啡杯paper towel 纸巾napkin 餐巾table cloth 桌布tea -pot 茶壶tea set 茶具tea tray 茶盘caddy 茶罐dish 碟plate 盘saucer 小碟子rice bowl 饭碗chopsticks 筷子soup spoon 汤匙knife 餐刀cup 杯子glass 玻璃杯mug 马克杯picnic lunch 便当fruit plate 水果盘toothpick 牙签中餐:bear's

Leetcode-1012 Complement of Base 10 Integer(十进制整数的补码)

1 #define _for(i,a,b) for(int i = (a);i < (b);i ++) 2 class Solution 3 { 4 public: 5 int bitwiseComplement(int N) 6 { 7 if(N==0) 8 return 1; 9 string s; 10 while(N) 11 { 12 s+= N%2+'0'; 13 N/=2; 14 } 15 reverse(s.begin(),s.end()); 16 17 _for(i,0,s.si

LeetCode 476. Number Complement(easy难度c++)

题目: Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation. Note: The given integer is guaranteed to fit within the range of a 32-bit signed integer. You could assume no leadin

聊一下补码1

对于补码一直只知道应用方法,就是正数的补码是其本身,负数的补码是其对应正数的每一位取反后加一,这样减法操作就可以用加法来实现.但是一直不太明了其原理,今天就来掰开揉碎了聊一下. 补码源自于数学上补数的概念和方法,所以理解补码必须先理解补数. 补数 补数(radix comletment)的定义:有一个以b为基数,位数为n的数字y,y的补数即是b的n次方减去y.例如,基数是10,三位数123的补数就是877(1000-123). 缩减基数补数(diminished radix complement

原码、反码、补码的产生、应用以及优缺点有哪些?

作者:张天行链接:https://www.zhihu.com/question/20159860/answer/119405396来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 二.重温运算规则 首先我想把整套关于原码反码补码的运算规则准确清晰地写一遍,方便急需应用的知友参考,也希望大家首先能记住这套规定,再开始进一步的探讨. 所谓原码就是机器数,是加了一位符号位的二进制数,正数符号位为0,负数符号位为1,计算机中存储.处理.运算的数据通常是8位.16位.32位或

计算机中的整数(原码、反码、补码)

系统中所有的信息——包括磁盘文件.存储器中的程序存储器中存放的用户数据以及网上落上传送的数据,都是由一串位表示的.区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文.比如,在不同的上下文中,一个同样的字节序列可能表示一个整数.浮点数.字符串或者机器指令. 计算机中的整数可以分为无符号整数和有符号整数两种类型.无符号整数不存在正负之分,在计算机中以其二进制真值的形式存放.而有符号整数由于有正负数的区分,表示相对复杂. 计算机中的符号数有三种表示方法,即原码.反码和补码.三种表示方法均有符号

关于二进制补码

转:http://www.ruanyifeng.com/blog/2009/08/twos_complement.html 问一个主要的问题. 负数在计算机中怎样表示? 举例来说,+8在计算机中表示为二进制的1000,那么-8怎么表示呢? 非常easy想到,能够将一个二进制位(bit)专门规定为符号位,它等于0时就表示正数,等于1时就表示负数.比方,在8位机中,规定每一个字节的最高位为符号位.那么,+8就是00001000,而-8则是10001000. 可是,随便找一本<计算机原理>,都会告诉

关于计算机中的《补码》,公式:-n=~n+1 引伸:~n=-n-1

在计算机系统中,数值一律用补码来表示(存储).主要原因是使用补码可以将符号位和其他位统一处理:同时,减法也可以按加法来处理.另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃.补码跟源码的转换过程几乎是相同的. 补码概述 求给定数值的补码表示分以下两种情况: ⑴正数的补码 与 原码 相同. [例1]+9的补码是00001001.(备注:这个+9的补码说的是用8位的2进制来表示补码的,补码表示方式很多,还有16位2进制补码表示形式,以及32位2进制补码表示形式等.) ⑵负数的

补码与模

一.本篇来由 昨天进行了反码.补码那些和浮点数的研究,但是还有一些问题遗漏,晚上跟寝室众基友讨论了,反而提出来一个很有意思的问题,于是有了本篇~~我们并不知道为什么有补码这个东西,只知道在计算机中广泛用补码存储,不知道为什么叫"补"码. 二.模 "模"是指一个计量系统的计数范围.如时钟等.计算机也可以看成一个计量机器,它也有一个计量范 围,即都存在一个"模". 例如: 时钟的计量范围是0-11,模=12. 表示n位的计算机计量范围是0-2(n)-