我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
当前回答
想象一下,你有有限数量的比特/比特/数字等等。将0定义为所有数字都为0,并自然向上计数:
00
01
02
..
最终你会溢出。
98
99
00
我们有两位数字,可以表示从0到100的所有数字。所有这些数字都是正数!假设我们也想表示负数?
我们真正拥有的是一个循环。2之前的数字是1。1之前的数字是0。0之前的数字是…99.
为了简单起见,我们设任何大于50的数都是负数。0 ~ 49代表0 ~ 49。“99”是-1,“98”是-2,…“50”是-50。
这个表示是十的补数。计算机通常使用2的补码,除了使用位而不是数字之外,它是一样的。
10的补数的好处在于加法运算可以正常进行。你不需要做任何特殊的加法和负数!
其他回答
最简单的答案:
1111 + 1 =(1)0000。所以1111一定是-1。那么-1 + 1 = 0。
理解这些对我来说是完美的。
简单来说,2的补码是一种在计算机内存中存储负数的方法。而正数则存储为普通二进制数。
让我们考虑这个例子,
计算机使用二进制数字系统来表示任何数字。
x = 5;
这表示为0101。
x = -5;
当计算机遇到-号时,它会计算出它的2的补数并存储它。
也就是说,5 = 0101,它的2的补是1011。
计算机处理数字的重要规则是,
如果第一位是1,那么它一定是负数。 如果除第1位之外的所有位都是0,那么它就是一个正数,因为在数字系统中没有-0(1000不是-0,而是正8)。 如果所有的位都是0,那么它就是0。 否则就是正数。
通过对给定数的第1个补数加1,可以求出两个补数。 假设我们要求出10101的两个补,然后求出它的一个补,也就是,在这个结果上加1,也就是,01010+1=01011,这就是最终答案。
这是一种对负整数进行编码的聪明方法,该方法将数据类型中大约一半的位组合保留给负整数,并且将大多数负整数与其对应的正整数相加会导致进位溢出,使结果为二进制零。
因此,在2的补码中,如果1是0x0001,那么-1是0x1111,因为这将导致0x0000的组合和(溢出1)。
按位补一个数就是将其中的所有位翻转。对2的补位,我们翻转所有的位,加1。
对有符号整数使用2的补码表示,我们应用2的补码操作将正数转换为负数,反之亦然。因此,以nibbles为例,0001(1)变成1111(-1),并再次应用该操作,返回0001。
零处操作的行为有利于给出零的单一表示,而无需特别处理正零和负零。0000与1111互补,当1111加1时。溢出到0000,得到一个0,而不是一个正1和一个负1。
这种表示的一个关键优点是,用于无符号整数的标准加法电路在应用于它们时产生正确的结果。例如,在nibbles中添加1和-1:0001 + 1111,比特溢出寄存器,留下0000。
作为一个温和的介绍,优秀的Computerphile制作了一个关于这个主题的视频。