我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
当前回答
从数学的角度来看这两个补体系统是有道理的。在ten的补语中,这个想法本质上是“隔离”差异。
示例:63 - 24 = x
我们把24的补数相加,也就是(100 - 24)实际上,我们要做的就是在方程两边加100。
现在方程是:100 + 63 - 24 = x + 100,这就是为什么我们要去掉100(或10或1000或其他)。
由于必须从一长串零中减去一个数字的不方便情况,我们使用“减基数补”系统,在十进制系统中,9的补。
当我们看到一串大的9减去一个数时,我们只需要把数字倒过来。
例如:99999 - 03275 = 96724
这就是为什么在9的补数之后加1。你可能从儿时的数学中知道,9通过“偷走”1变成了10。所以基本上就是10的补位差减去1。
在二进制中,2的补数等于10的补数,而1的补数等于9的补数。主要的区别在于,我们不是试图用10的幂来分离差异(将10、100等添加到等式中),而是试图用2的幂来分离差异。
正是因为这个原因,我们把比特位颠倒。就像小数中的被减数是一串9一样,二进制中的被减数也是一串1。
例如:111111 - 101001 = 010110
因为1链比2的幂小1,它们从差值中“偷”了1,就像小数点中的9一样。
当我们使用负二进制数时,我们实际上是在说
0000 - 0101 = x
1111-0101 = 1010
1111 + 0000 - 0101 = x + 1111
为了“分离”x,我们需要加1,因为1111离10000只有1,我们去掉前导的1,因为我们只是把它加到原始的差值上。
1111 + 1 + 0000 - 0101 = x + 1111 + 1
10000 + 0000 - 0101 = x + 10000
只要两边都去掉10000就得到x,这是基本的代数。
其他回答
Two的补码是一种存储整数的聪明方法,因此常见的数学问题很容易实现。
为了理解,你必须把数字想象成二进制。
它基本上是说,
对于0,用所有的0。 对于正整数,开始计数,最大值为2(位数-1)-1。 对于负整数,做完全相同的事情,但是切换0和1的角色并开始倒数(所以不是从0000开始,而是从1111开始——这是“补”部分)。
让我们尝试一个4位的迷你字节(我们称之为1/2个字节)。
0000 -零 0001 - 1 0010 - 2 0011 - 3 0100到0111,4点到7点
这是我们目前能找到的阳性结果。23-1 = 7。
负面影响:
1111 - 1 1110 - 2 1101 - 3 1100到1000 - - 4到- 8
注意,负数(1000 = -8)有一个额外的值,而正数没有。这是因为0000用于表示零。这可以看作是计算机的数轴。
区分正数和负数
这样一来,第一个位就扮演了“符号”位的角色,因为它可以用来区分非负的十进制值和负的十进制值。如果最高有效位是1,那么二进制就可以说是负的,如果最高有效位(最左边)是0,就可以说十进制值是非负的。
“符号量级”的负数只是将它们的正数对应的符号位颠倒了,但这种方法必须处理将1000(一个1后面跟着所有的0)解释为“负零”,这是令人困惑的。
“1的补”负数只是它们的正数的位补,这也导致了“负零”和1111(都是1)的混淆。
除非你的工作非常接近硬件,否则你可能不需要处理个位补或符号幅度整数表示。
2的补码是表示负数的一种方式,大多数控制器和处理器都以2的补码形式存储负数。
两人的补足(托马斯·芬利)
我把所有位的倒数加1。编程:
// In C++11
int _powers[] = {
1,
2,
4,
8,
16,
32,
64,
128
};
int value = 3;
int n_bits = 4;
int twos_complement = (value ^ ( _powers[n_bits]-1)) + 1;
你也可以使用在线计算器来计算一个十进制数的补二表示:http://www.convertforfree.com/twos-complement-calculator/
这是一种对负整数进行编码的聪明方法,该方法将数据类型中大约一半的位组合保留给负整数,并且将大多数负整数与其对应的正整数相加会导致进位溢出,使结果为二进制零。
因此,在2的补码中,如果1是0x0001,那么-1是0x1111,因为这将导致0x0000的组合和(溢出1)。