Binary 什么是“;2';s补码”;?
我学的是计算机系统课程,在某种程度上,我一直在努力学习。我想理解它,但我读过的每一篇文章都没有让我明白。我已经读过这本书和其他各种文章,包括 因此,我想开始这篇社区wiki文章,来定义什么是二的补码,如何使用它,以及它在诸如强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中如何影响数字 我希望的是一个清晰简洁的定义,程序员很容易理解。是一种存储整数的聪明方法,因此常见的数学问题很容易实现 要想理解,你必须想到这些数字 它基本上说,Binary 什么是“;2';s补码”;?,binary,bit-manipulation,computer-science,twos-complement,data-representation,Binary,Bit Manipulation,Computer Science,Twos Complement,Data Representation,我学的是计算机系统课程,在某种程度上,我一直在努力学习。我想理解它,但我读过的每一篇文章都没有让我明白。我已经读过这本书和其他各种文章,包括 因此,我想开始这篇社区wiki文章,来定义什么是二的补码,如何使用它,以及它在诸如强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中如何影响数字 我希望的是一个清晰简洁的定义,程序员很容易理解。是一种存储整数的聪明方法,因此常见的数学问题很容易实现 要想理解,你必须想到这些数字 它基本上说, 对于零,使用所有0 对于正整数,开始计数,最
- 对于零,使用所有0
- 对于正整数,开始计数,最大值为2(位数-1)-1
- 对于负整数,执行完全相同的操作,但是切换0和1的角色(因此,不要从0000开始,而是从1111开始-这是“补码”部分)
-零0000
-一个0001
-两个0010
-三个0011
到0100
-四到七0111
-负数1111
-负二1110
-负三1101
至1100
-负四至负八1000
1000
=-8),您会得到一个额外的值,而对于正数,您不会得到这个值。这是因为0000
用于零。这可以被看作是计算机的一个例子
区分正数和负数
这样做,第一位获得“符号”位的角色,因为它可以用来区分非负和负十进制值。如果最高有效位是1
,则二进制可以说是负数,其中最高有效位(最左边)是0
,可以说十进制值是非负数
负数只是将正数对应的符号位翻转,但这种方法必须将1000
(一个1
,后跟所有0
s)解释为“负零”,这很容易混淆
负数只是正数对应项的位补码,这也会导致将“负零”与1111
(所有数字)混淆
除非您的工作离硬件非常近,否则您可能不必处理一的补码或符号大小整数表示。我想知道这是否比维基百科的文章解释得更好 用二的补码表示法试图解决的基本问题是存储负整数的问题
首先,考虑一个以4位存储的无符号整数。你可以有以下几点
0000 = 0
0001 = 1
0010 = 2
...
1111 = 15
这些是无符号的,因为没有迹象表明它们是负数还是正数
符号大小和多余符号
要存储负数,可以尝试多种方法。首先,可以使用符号幅度表示法,将第一位指定为符号位以表示+/-,其余位表示幅度。再次使用4位,假设1表示-,0表示+那么你就有了
0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7
你看到问题了吗?我们有正0和负0。更大的问题是二进制数的加减。使用符号幅度进行加法和减法的电路将非常复杂
什么是
0010
1001 +
----
?
另一个系统是。你可以存储负数,你可以摆脱两个零的问题,但加法和减法仍然很困难
于是,二的补码出现了。现在,您可以相对轻松地存储正整数和负整数并执行算术。有许多方法可以将一个数字转换为二的补码。这里有一个
将十进制转换为二的补码
2 = 0010
-3 = 1101 +
-------------
-1 = 1111
将二的补码转换为十进制
将1111转换为十进制:
塔达 我喜欢拉维尼奥的答案,但移位会增加一些复杂性。通常,在考虑符号位或不考虑符号位时,可以选择移动位。这是将数字视为有符号数字(半字节为8到7,字节为128到127)或全范围无符号数字(半字节为0到15,字节为0到255)之间的选择。假设您有有限数量的位/trits/位/任何数字。您将0定义为所有数字均为0,并自然向上计数:
00
01
02
..
最终你会溢出
98
99
00
我们有两个数字,可以代表从0到100的所有数字。所有这些号码都是po
00001010
11110100
-----------------
11111110
// 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;
35=035=000000035.
[0101]=[00101]=[00000000000101]=5 (base 10)
[1011]=[11011]=[11111111111011]=-5(base 10)
if a >= 0 then |a| = a
if a < 0 then |a| = -a = 2scomplement of a
1'scomp(0101) = 1010.
Example 1 Example 2
0101 --original number 1101
1's comp 1010 0010
add 1 0001 0001
2's comp 1011 --negated number 0011
1110 Carry 00000 Carry
0110 is the same as 00110
-0111 +11001
---------- ----------
sum 0101 sum 11111
1 1 1
----------
1 0 1
1 0 1 1 ---> additive inverse
---------
0 0 0
x = 5;
x = -5;