什么是“二进制补码”?

发布于 2024-07-25 12:02:35 字数 436 浏览 5 评论 0原文

我正在学习计算机系统课程,并且一直在挣扎,部分原因是二进制补码。 我想理解它,但我读过的所有内容都没有为我提供完整的图片。 我已阅读维基百科文章和各种其他文章,包括我的教科书

什么是二进制补码,我们如何使用它以及它如何在强制转换(从有符号到无符号,反之亦然)、按位运算和位移运算等操作中影响数字?

I'm in a computer systems course and have been struggling, in part, with two's complement. I want to understand it, but everything I've read hasn't brought the picture together for me. I've read the Wikipedia article and various other articles, including my text book.

What is two's complement, how can we use it and how can it affect numbers during operations like casts (from signed to unsigned and vice versa), bit-wise operations and bit-shift operations?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

萌能量女王 2024-08-01 12:02:35

二进制补码是一种存储整数的巧妙方法,因此常见的数学问题很容易实现。

要理解,您必须考虑二进制中的数字。

它基本上是说,

  • 对于零,使用全 0。
  • 对于正整数,开始向上计数,最大为 2(位数 - 1)-1。
  • 对于负整数,做完全相同的事情,但交换 0 和 1 的角色并倒数(因此不是从 0000 开始,而是从 1111 开始 - 这是“补数”部分)。

让我们尝试使用 4 位的迷你字节(我们将其称为 半字节 - 1 /2 一个字节)。

  • 0000 - 零
  • 0001 - 一
  • 0010 - 两个
  • 0011 - 三
  • 0100 到 < code>0111 - 四到七

这是我们所能得出的积极结果。 23-1 = 7.

对于负数:

  • 1111 - 负一
  • 1110 - 负二
  • 1101 - 负三
  • 11001000 - 负四到负八

请注意,对于负数,您会得到一个额外的值 (1000 = -8),而您没有为了积极的一面。 这是因为 0000 用于表示零。 这可以被视为计算机的数轴

区分正数和负数

这样做时,第一位将扮演“符号”位的角色,因为它可用于区分非负十进制值和负十进制值。 如果最高有效位是1,则二进制可以说是负数,如果最高有效位(最左边)是0,则可以说小数值是非负的。

"Sign-magnitude" 负数只是将正数的符号位翻转,但是这种方法必须将 1000(一个 1 后跟所有 0)解释为“负零”,这很令人困惑。

“个数补码” 负数只是其正数的位补码,还会导致与 1111 (全一)混淆的“负零”。

除非您的工作非常接近硬件,否则您可能不需要处理补码或符号数值整数表示。

Two's complement is a clever way of storing integers so that common math problems are very simple to implement.

To understand, you have to think of the numbers in binary.

It basically says,

  • for zero, use all 0's.
  • for positive integers, start counting up, with a maximum of 2(number of bits - 1)-1.
  • for negative integers, do exactly the same thing, but switch the role of 0's and 1's and count down (so instead of starting with 0000, start with 1111 - that's the "complement" part).

Let's try it with a mini-byte of 4 bits (we'll call it a nibble - 1/2 a byte).

  • 0000 - zero
  • 0001 - one
  • 0010 - two
  • 0011 - three
  • 0100 to 0111 - four to seven

That's as far as we can go in positives. 23-1 = 7.

For negatives:

  • 1111 - negative one
  • 1110 - negative two
  • 1101 - negative three
  • 1100 to 1000 - negative four to negative eight

Note that you get one extra value for negatives (1000 = -8) that you don't for positives. This is because 0000 is used for zero. This can be considered as Number Line of computers.

Distinguishing between positive and negative numbers

Doing this, the first bit gets the role of the "sign" bit, as it can be used to distinguish between nonnegative and negative decimal values. If the most significant bit is 1, then the binary can be said to be negative, where as if the most significant bit (the leftmost) is 0, you can say the decimal value is nonnegative.

"Sign-magnitude" negative numbers just have the sign bit flipped of their positive counterparts, but this approach has to deal with interpreting 1000 (one 1 followed by all 0s) as "negative zero" which is confusing.

"Ones' complement" negative numbers are just the bit-complement of their positive counterparts, which also leads to a confusing "negative zero" with 1111 (all ones).

You will likely not have to deal with Ones' Complement or Sign-Magnitude integer representations unless you are working very close to the hardware.

单身狗的梦 2024-08-01 12:02:35

我想知道是否可以比维基百科文章更好地解释它。

您试图用二进制补码表示解决的基本问题是存储负整数的问题。

首先,考虑以 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 +
----

另一个系统是 多余的符号。 您可以存储负数,摆脱两个零的问题,但加法和减法仍然很困难。

因此随之而来的是二进制补码。 现在您可以存储正整数和负整数并相对轻松地执行算术运算。 有多种方法可以将数字转换为二进制补码。 这是一个。

将十进制转换为二进制补码

  1. 将数字转换为二进制(暂时忽略符号)
    例如 5 是 0101,-5 是 0101

  2. 如果该数字是正数,则完成。
    例如,使用二进制补码表示法,5 是二进制的 0101。

  3. 如果数字为负数,则

    3.1 求补码(反转 0 和 1)
    例如 -5 是 0101,所以求补码是 1010

    3.2 补码 1010 + 1 = 1011 加 1。
    因此,-5 的补码为 1011。

那么,如果您想用二进制表示 2 + (-3) 该怎么办? 2+(-3) 是-1。
如果您使用符号幅度来添加这些数字,您需要做什么? 0010 + 1101 = ?

考虑一下使用二进制补码是多么容易。

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111

将二进制补码转换为十进制

将 1111 转换为十进制:

  1. 该数字以 1 开头,因此它是负数,因此我们找到 1111 的补码,即 0000。

  2. 0000加1,我们得到0001。

  3. 将 0001 转换为十进制,即 1。

  4. 应用符号 = -1。

田田!

I wonder if it could be explained any better than the Wikipedia article.

The basic problem that you are trying to solve with two's complement representation is the problem of storing negative integers.

First, consider an unsigned integer stored in 4 bits. You can have the following

0000 = 0
0001 = 1
0010 = 2
...
1111 = 15

These are unsigned because there is no indication of whether they are negative or positive.

Sign Magnitude and Excess Notation

To store negative numbers you can try a number of things. First, you can use sign magnitude notation which assigns the first bit as a sign bit to represent +/- and the remaining bits to represent the magnitude. So using 4 bits again and assuming that 1 means - and 0 means + then you have

0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7

So, you see the problem there? We have positive and negative 0. The bigger problem is adding and subtracting binary numbers. The circuits to add and subtract using sign magnitude will be very complex.

What is

0010
1001 +
----

?

Another system is excess notation. You can store negative numbers, you get rid of the two zeros problem but addition and subtraction remains difficult.

So along comes two's complement. Now you can store positive and negative integers and perform arithmetic with relative ease. There are a number of methods to convert a number into two's complement. Here's one.

Convert Decimal to Two's Complement

  1. Convert the number to binary (ignore the sign for now)
    e.g. 5 is 0101 and -5 is 0101

  2. If the number is a positive number then you are done.
    e.g. 5 is 0101 in binary using two's complement notation.

  3. If the number is negative then

    3.1 find the complement (invert 0's and 1's)
    e.g. -5 is 0101 so finding the complement is 1010

    3.2 Add 1 to the complement 1010 + 1 = 1011.
    Therefore, -5 in two's complement is 1011.

So, what if you wanted to do 2 + (-3) in binary? 2 + (-3) is -1.
What would you have to do if you were using sign magnitude to add these numbers? 0010 + 1101 = ?

Using two's complement consider how easy it would be.

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111

Converting Two's Complement to Decimal

Converting 1111 to decimal:

  1. The number starts with 1, so it's negative, so we find the complement of 1111, which is 0000.

  2. Add 1 to 0000, and we obtain 0001.

  3. Convert 0001 to decimal, which is 1.

  4. Apply the sign = -1.

Tada!

悲欢浪云 2024-08-01 12:02:35

与我见过的大多数解释一样,上面的解释很清楚如何使用 2 的补码,但并没有真正从数学角度解释它们的含义。 我将尝试这样做,至少对于整数,并且我将首先介绍一些可能熟悉的背景知识。

回想一下十进制的用法:
  2345
是一种书写方式
  2 × 10 3 + 3 × 102 + 4 × 101 + 5 × 100

同样,二进制是一种仅使用 01 编写数字的方式,遵循相同的总体思路,但用 2 替换上面的 10。 那么在二进制中,
  1111
是一种书写方式
  1 × 23 + 1 × 22 + 1 × 21 + 1 × 20
如果计算出来,结果等于 15(以 10 为底)。 那是因为它是
  8+4+2+1 = 15。

对于正数来说,这一切都很好。 如果您愿意在负数前面添加一个减号,它甚至适用于负数,就像人类对十进制数所做的那样。 这甚至可以在计算机中完成,但自 20 世纪 70 年代初以来我还没有见过这样的计算机。 我将留下不同讨论的原因。

对于计算机来说,使用补码表示负数会更有效。 这是经常被忽视的事情。 补码表示法涉及数字数字的某种反转,甚至是正常正数之前的隐含零。 这很尴尬,因为问题出现了:所有这些? 这可能是无数个需要考虑的数字。

幸运的是,计算机并不代表无穷大。 数字被限制为特定的长度(或宽度,如果您愿意)。 因此,让我们回到正二进制数,但具有特定的大小。 对于这些示例,我将使用 8 位数字(“位”)。 所以我们的二进制数实际上是
  00001111

  0 × 27 + 0 × 26 + 0 × 25 + 0 × 2 4 + 1 × 23 + 1 × 22 + 1 × 2 1 + 1 × 20

要形成 2 的补码负数,我们首先对所有(二进制)数字进行补码以形成
   11110000
加1形成
  11110001
但是我们如何理解它的意思是-15呢?

答案是我们改变高位(最左边的一位)的含义。 对于所有负数,该位都是1。 更改将更改其对其出现的数字值的贡献的符号。因此现在我们的 11110001 被理解为代表
  -1 × 27 + 1 × 26 + 1 × 25 + 1 × 24 + 0 × 23 + 0 × 22 + 0 × 21 + 1 × 20
注意前面的“-”表达? 这意味着符号位的权重为-27,即-128(基数为10)。 所有其他位置保留与无符号二进制数相同的权重。

算出我们的 -15,它是
  -128 + 64 + 32 + 16 + 1
在计算器上试试。 是-15。

在我所看到的计算机中表示负数的三种主要方式中,2 的补码在一般使用中很方便。 不过,它有一个奇怪之处。 由于它是二进制的,因此必须有偶数个可能的位组合。 每个正数都可以与其负数配对,但只有一个零。 否定零就等于零。 因此,还有一种组合,即符号位中带有 1 且其他位置带有 0 的数字。 相应的正数不适合正在使用的位数。

这个数字更奇怪的是,如果你尝试通过补一和加一来形成它的正数,你会得到相同的负数。 零似乎很自然地会做到这一点,但这是意想不到的,而且根本不是我们习惯的行为,因为除了计算机之外,我们通常认为数字的无限供应,而不是这种固定长度的算术。

这就像怪事的冰山一角。 表面之下还有更多的事情等待着,但这对于本次讨论来说已经足够了。 如果您研究定点运算的“溢出”,您可能会发现更多信息。 如果你真的想深入研究,你也可以研究“模算术”。

Like most explanations I've seen, the ones above are clear about how to work with 2's complement, but don't really explain what they are mathematically. I'll try to do that, for integers at least, and I'll cover some background that's probably familiar first.

Recall how it works for decimal:
  2345
is a way of writing
  2 × 103 + 3 × 102 + 4 × 101 + 5 × 100.

In the same way, binary is a way of writing numbers using just 0 and 1 following the same general idea, but replacing those 10s above with 2s. Then in binary,
  1111
is a way of writing
  1 × 23 + 1 × 22 + 1 × 21 + 1 × 20
and if you work it out, that turns out to equal 15 (base 10). That's because it is
  8+4+2+1 = 15.

This is all well and good for positive numbers. It even works for negative numbers if you're willing to just stick a minus sign in front of them, as humans do with decimal numbers. That can even be done in computers, sort of, but I haven't seen such a computer since the early 1970's. I'll leave the reasons for a different discussion.

For computers it turns out to be more efficient to use a complement representation for negative numbers. And here's something that is often overlooked. Complement notations involve some kind of reversal of the digits of the number, even the implied zeroes that come before a normal positive number. That's awkward, because the question arises: all of them? That could be an infinite number of digits to be considered.

Fortunately, computers don't represent infinities. Numbers are constrained to a particular length (or width, if you prefer). So let's return to positive binary numbers, but with a particular size. I'll use 8 digits ("bits") for these examples. So our binary number would really be
  00001111
or
  0 × 27 + 0 × 26 + 0 × 25 + 0 × 24 + 1 × 23 + 1 × 22 + 1 × 21 + 1 × 20

To form the 2's complement negative, we first complement all the (binary) digits to form
  11110000
and add 1 to form
  11110001
but how are we to understand that to mean -15?

The answer is that we change the meaning of the high-order bit (the leftmost one). This bit will be a 1 for all negative numbers. The change will be to change the sign of its contribution to the value of the number it appears in. So now our 11110001 is understood to represent
  -1 × 27 + 1 × 26 + 1 × 25 + 1 × 24 + 0 × 23 + 0 × 22 + 0 × 21 + 1 × 20
Notice that "-" in front of that expression? It means that the sign bit carries the weight -27, that is -128 (base 10). All the other positions retain the same weight they had in unsigned binary numbers.

Working out our -15, it is
  -128 + 64 + 32 + 16 + 1
Try it on your calculator. it's -15.

Of the three main ways that I've seen negative numbers represented in computers, 2's complement wins hands down for convenience in general use. It has an oddity, though. Since it's binary, there have to be an even number of possible bit combinations. Each positive number can be paired with its negative, but there's only one zero. Negating a zero gets you zero. So there's one more combination, the number with 1 in the sign bit and 0 everywhere else. The corresponding positive number would not fit in the number of bits being used.

What's even more odd about this number is that if you try to form its positive by complementing and adding one, you get the same negative number back. It seems natural that zero would do this, but this is unexpected and not at all the behavior we're used to because computers aside, we generally think of an unlimited supply of digits, not this fixed-length arithmetic.

This is like the tip of an iceberg of oddities. There's more lying in wait below the surface, but that's enough for this discussion. You could probably find more if you research "overflow" for fixed-point arithmetic. If you really want to get into it, you might also research "modular arithmetic".

顾忌 2024-08-01 12:02:35

2的补码对于查找二进制值非常有用,但是我想到了一种更简洁的方法来解决这样的问题(从未见过其他人发布它):

采用二进制,例如:1101,它是[假设空间“1”是符号]等于-3

使用 2 的补码,我们可以这样做...将 1101 翻转到 0010...添加 0001 + 0010 ===> 给我们 0011。正二进制的 0011 = 3。因此 1101 = -3

我意识到:

您可以使用解决正二进制(假设 0101)的基本方法,而不是所有翻转和添加,即 (2 3 * 0) + (22 * 1) + (21 * 0) + (20 * 1) = 5.

用否定做完全相同的概念!(稍作改动)

以 1101 为例:

第一个数字代替 23 * 1 = < strong>8 ,执行 -(23 * 1) = -8

然后照常继续,执行 -8 + (22 * 1) + (21 * 0) + (20 * 1) = -3

2's complement is very useful for finding the value of a binary, however I thought of a much more concise way of solving such a problem(never seen anyone else publish it):

take a binary, for example: 1101 which is [assuming that space "1" is the sign] equal to -3.

using 2's complement we would do this...flip 1101 to 0010...add 0001 + 0010 ===> gives us 0011. 0011 in positive binary = 3. therefore 1101 = -3!

What I realized:

instead of all the flipping and adding, you can just do the basic method for solving for a positive binary(lets say 0101) is (23 * 0) + (22 * 1) + (21 * 0) + (20 * 1) = 5.

Do exactly the same concept with a negative!(with a small twist)

take 1101, for example:

for the first number instead of 23 * 1 = 8 , do -(23 * 1) = -8.

then continue as usual, doing -8 + (22 * 1) + (21 * 0) + (20 * 1) = -3

偏爱自由 2024-08-01 12:02:35

想象一下,您有有限数量的位/字符/数字/任何东西。 你将 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。

这种表示法是十的补码。 计算机通常使用二进制补码,除了使用位而不是数字之外,其他都是相同的。

十补码的好处是加法可以正常工作。 您不需要做任何特殊的事情来添加正数和负数!

Imagine that you have a finite number of bits/trits/digits/whatever. You define 0 as all digits being 0, and count upwards naturally:

00
01
02
..

Eventually you will overflow.

98
99
00

We have two digits and can represent all numbers from 0 to 100. All those numbers are positive! Suppose we want to represent negative numbers too?

What we really have is a cycle. The number before 2 is 1. The number before 1 is 0. The number before 0 is... 99.

So, for simplicity, let's say that any number over 50 is negative. "0" through "49" represent 0 through 49. "99" is -1, "98" is -2, ... "50" is -50.

This representation is ten's complement. Computers typically use two's complement, which is the same except using bits instead of digits.

The nice thing about ten's complement is that addition just works. You do not need to do anything special to add positive and negative numbers!

心房的律动 2024-08-01 12:02:35

我使用里程表在 Reddit 上在 Reddit 上读到了一篇很棒的解释作为一个类比。

输入图像描述这里

这是一个有用的约定。 相同的电路和逻辑运算
二进制正数加/减仍然适用于正数
如果使用约定则为负数,这就是为什么它如此
有用且无所不在。

想象一下汽车的里程表,它会在(比如说)99999 处滚动。如果你
递增 00000,得到 00001。如果递减 00000,得到 99999
(由于滚动)。 如果你在 99999 上加一,它就会回到
00000。因此确定 99999 代表 -1 很有用。 同样,确定 99998 代表 -2 等也非常有用。 你有
停在某处,并且按照惯例,停在数字的上半部分
被视为负数(50000-99999),下半部分为正数
只代表自己(00000-49999)。 结果,最高位的数字
5-9表示所表示的数为负数,0-4表示所表示的数
表示所表示的是正数 - 与最高位完全相同
表示二进制补码二进制数中的符号。

理解这一点对我来说也很难。 一旦我得到它并返回
重新阅读书籍文章和解释(没有互联网
那时),事实证明很多描述它的人并没有真正做到这一点
明白它。 之后我确实写了一本教汇编语言的书
那个(十年来卖得很好)。

I read a fantastic explanation on Reddit by jng, using the odometer as an analogy.

enter image description here

It is a useful convention. The same circuits and logic operations that
add / subtract positive numbers in binary still work on both positive
and negative numbers if using the convention, that's why it's so
useful and omnipresent.

Imagine the odometer of a car, it rolls around at (say) 99999. If you
increment 00000 you get 00001. If you decrement 00000, you get 99999
(due to the roll-around). If you add one back to 99999 it goes back to
00000. So it's useful to decide that 99999 represents -1. Likewise, it is very useful to decide that 99998 represents -2, and so on. You have
to stop somewhere, and also by convention, the top half of the numbers
are deemed to be negative (50000-99999), and the bottom half positive
just stand for themselves (00000-49999). As a result, the top digit
being 5-9 means the represented number is negative, and it being 0-4
means the represented is positive - exactly the same as the top bit
representing sign in a two's complement binary number.

Understanding this was hard for me too. Once I got it and went back to
re-read the books articles and explanations (there was no internet
back then), it turned out a lot of those describing it didn't really
understand it. I did write a book teaching assembly language after
that (which did sell quite well for 10 years).

陪你搞怪i 2024-08-01 12:02:35

给定数的第一个补数加上一即可得出二补数。
假设我们必须找出 10101 的二进制补码,然后找到它的补码,即 010101 添加到这个结果,即,01010+1=01011,这就是最终的答案。

Two complement is found out by adding one to 1'st complement of the given number.
Lets say we have to find out twos complement of 10101 then find its ones complement, that is, 01010 add 1 to this result, that is, 01010+1=01011, which is the final answer.

嘦怹 2024-08-01 12:02:35

让我们使用 8 位以二进制形式得到答案 10 – 12:
我们真正要做的是 10 + (-12)

我们需要得到 12 的补数部分,以便从 10 中减去它。
12 的二进制为 00001100。
二进制的 10 是 00001010。

为了得到 12 的补码部分,我们只需反转所有位,然后加 1。
12 的二进制反转后是 11110011。这也是反码(补码)。
现在我们需要加一,现在是 11110100。

所以 11110100 是 12 的补数! 当你这样想的时候就很容易了。

现在你可以用二进制形式解决上面的 10 - 12 问题。

00001010
11110100
-----------------
11111110  

Lets get the answer 10 – 12 in binary form using 8 bits:
What we will really do is 10 + (-12)

We need to get the compliment part of 12 to subtract it from 10.
12 in binary is 00001100.
10 in binary is 00001010.

To get the compliment part of 12 we just reverse all the bits then add 1.
12 in binary reversed is 11110011. This is also the Inverse code (one's complement).
Now we need to add one, which is now 11110100.

So 11110100 is the compliment of 12! Easy when you think of it this way.

Now you can solve the above question of 10 - 12 in binary form.

00001010
11110100
-----------------
11111110  
瘫痪情歌 2024-08-01 12:02:35

到目前为止,许多答案很好地解释了为什么用二进制补码来表示负数,但没有告诉我们二进制补码是什么,特别是没有告诉我们为什么添加“1”,而且实际上经常以错误的方式添加。

造成混乱的原因是对补数定义的理解不足。 补语是使某件事变得完整的缺失部分。

根据定义,基数 b 中 n 位数字 x 的基数补为 b^nx。

在二进制中,4 由 100 表示,它有 3 位数字 (n=3),基数为 2 (b=2)。 所以它的基数补码是b^nx = 2^3-4=8-4=4(或二进制的100)。

然而,在二进制中获得基数的补码并不像获得其减基补码那么容易,减基补码定义为(b^n-1)-y,仅比基数补码少1。 要获得减基数补码,只需翻转所有数字即可。

100-> 011(减(一)基数补码)

要获得基(二)补码,我们只需加 1,如定义所定义。

011 +1 ->100(二进制补码)。

现在有了这个新的理解,让我们看一下 Vincent Ramdhanie 给出的示例(见上面第二个回复):

将 1111 转换为十进制:

这个数字是从1开始的,所以它是负数,所以我们找到1111的补码,即0000。
0000 加 1,得到 0001。
将 0001 转换为十进制,即 1。
应用符号 = -1。
多田!

应该理解为:

数字是从1开始的,所以是负数。 所以我们知道它是某个值 x 的二进制补码。 为了找到由其补码表示的 x,我们首先需要找到其补码。

x 的二进制补码:1111
x的补码:1111-1→1110;
x = 0001,(翻转所有数字)

应用符号 -,答案 =-x =-1。

Many of the answers so far nicely explain why two's complement is used to represent negative numbers, but do not tell us what two's complement number is, particularly not why a '1' is added, and in fact often added in a wrong way.

The confusion comes from a poor understanding of the definition of a complement number. A complement is the missing part that would make something complete.

The radix complement of an n digit number x in radix b is, by definition, b^n-x.

In binary 4 is represented by 100, which has 3 digits (n=3) and a radix of 2 (b=2). So its radix complement is b^n-x = 2^3-4=8-4=4 (or 100 in binary).

However, in binary obtaining a radix's complement is not as easy as getting its diminished radix complement, which is defined as (b^n-1)-y, just 1 less than that of radix complement. To get a diminished radix complement, you simply flip all the digits.

100 -> 011 (diminished (one's) radix complement)

to obtain the radix (two's) complement, we simply add 1, as the definition defined.

011 +1 ->100 (two's complement).

Now with this new understanding, let's take a look of the example given by Vincent Ramdhanie (see above second response):

Converting 1111 to decimal:

The number starts with 1, so it's negative, so we find the complement of 1111, which is 0000.
Add 1 to 0000, and we obtain 0001.
Convert 0001 to decimal, which is 1.
Apply the sign = -1.
Tada!

Should be understood as:

The number starts with 1, so it's negative. So we know it is a two's complement of some value x. To find the x represented by its two's complement, we first need find its 1's complement.

two's complement of x: 1111
one's complement of x: 1111-1 ->1110;
x = 0001, (flip all digits)

Apply the sign -, and the answer =-x =-1.

那片花海 2024-08-01 12:02:35

从数学的角度来看补码系统,这确实很有意义。 在十的补码中,这个想法本质上是“隔离”差异。

示例:63 - 24 = x

我们添加 24 的补码,实际上就是 (100 - 24)。 所以实际上,我们所做的只是在等式两边加上 100。

现在等式是:100 + 63 - 24 = x + 100,这就是为什么我们删除 100(或 10 或 1000 或其他)。

由于必须从一长串零中减去一个数字的不方便情况,我们使用“减基数补码”系统,在十进制系统中,即九的补码。

当我们看到从一大串 9 中减去一个数字时,我们只需要将数字反转即可。

示例:99999 - 03275 = 96724

这就是原因,在九的补码之后,我们添加 1。正如您可能从童年数学中知道的那样,通过“偷”1,9 变成了 10。所以基本上,这只是十的补码从差值中取 1。

在二进制中,二的补码等于十的补码,而一的补码等于九的补码。 主要区别在于,我们不是尝试用 10 的幂来隔离差异(在方程中添加 10、100 等),而是尝试用 2 的幂来隔离差异。

正是出于这个原因,我们反转了这些位。 就像我们的被减数是十进制中的一串九一样,我们的被减数也是二进制中的一串。

示例:111111 - 101001 = 010110

因为 1 链的值小于 2 的幂,所以它们从差值中“窃取”1,就像十进制中的 9 一样。

当我们使用负二进制数时,我们实际上只是在说:

0000 - 0101 = x

1111 - 0101 = 1010

1111 + 0000 - 0101 = x + 1111

为了“隔离”x,我们需要加 1,因为 1111 是 1远离 10000,我们删除前导 1,因为我们只是将其添加到原始差值中。

1111 + 1 + 0000 - 0101 = x + 1111 + 1

10000 + 0000 - 0101 = x + 10000

两边去掉 10000 就得到 x,这是基本代数。

Looking at the two's complement system from a math point of view it really makes sense. In ten's complement, the idea is to essentially 'isolate' the difference.

Example: 63 - 24 = x

We add the complement of 24 which is really just (100 - 24). So really, all we are doing is adding 100 on both sides of the equation.

Now the equation is: 100 + 63 - 24 = x + 100, that is why we remove the 100 (or 10 or 1000 or whatever).

Due to the inconvenient situation of having to subtract one number from a long chain of zeroes, we use a 'diminished radix complement' system, in the decimal system, nine's complement.

When we are presented with a number subtracted from a big chain of nines, we just need to reverse the numbers.

Example: 99999 - 03275 = 96724

That is the reason, after nine's complement, we add 1. As you probably know from childhood math, 9 becomes 10 by 'stealing' 1. So basically it's just ten's complement that takes 1 from the difference.

In Binary, two's complement is equatable to ten's complement, while one's complement to nine's complement. The primary difference is that instead of trying to isolate the difference with powers of ten (adding 10, 100, etc. into the equation) we are trying to isolate the difference with powers of two.

It is for this reason that we invert the bits. Just like how our minuend is a chain of nines in decimal, our minuend is a chain of ones in binary.

Example: 111111 - 101001 = 010110

Because chains of ones are 1 below a nice power of two, they 'steal' 1 from the difference like nine's do in decimal.

When we are using negative binary number's, we are really just saying:

0000 - 0101 = x

1111 - 0101 = 1010

1111 + 0000 - 0101 = x + 1111

In order to 'isolate' x, we need to add 1 because 1111 is one away from 10000 and we remove the leading 1 because we just added it to the original difference.

1111 + 1 + 0000 - 0101 = x + 1111 + 1

10000 + 0000 - 0101 = x + 10000

Just remove 10000 from both sides to get x, it's basic algebra.

我三岁 2024-08-01 12:02:35

补充这个词源自完整性。 在十进制世界中,数字 0 到 9 提供了数字或数字符号的补码(完整集)来表示所有十进制数字。 在二进制世界中,数字 0 和 1 提供了数字的补码来表示所有二进制数。 事实上,符号 0 和 1 必须用来表示一切(文本、图像等)以及正(0)和负(1)。
在我们的世界中,数字左侧的空格被视为零:

                  35=035=000000035.

在计算机存储位置中没有空格。 所有位(二进制数字)必须为 0 或 1。为了有效地使用存储器,数字可以存储为 8 位、16 位、32 位、64 位、128 位表示形式。 当存储为 8 位数字的数字传输到 16 位位置时,符号和大小(绝对值)必须保持相同。 1 的补码和 2 的补码表示法都有助于实现这一点。
作为名词:
1 的补码和 2 的补码都是有符号量的二进制表示形式,其中最高有效位(左边的那个)是符号位。 0 代表正,1 代表负。
2的补数并不意味着负数。 这意味着有签名的数量。 与十进制一样,大小表示为正数。 当提升到具有更多位的寄存器 [] 时,该结构使用符号扩展来保留数量:

       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)

作为动词:
2的补码意味着否定。 这并不意味着消极。 这意味着如果负数变为正数; 如果为正,则为负。 幅度是绝对值:

        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a

此功能允许使用先取后加的方式进行高效的二进制减法。
a - b = a + (-b)

获取 1 的补码的官方方法是用 1 减去每个数字的值。

        1'scomp(0101) = 1010.

这与单独翻转或反转每个位相同。 这会导致负零,但人们不太喜欢这种负零,因此在 1 的补码上加 1 就可以解决这个问题。
要取反或取 2 的补码,首先取 1 的补码,然后加 1。

        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 进位 111110 进位
0110 与 000110 相同
1111 111111
sum 0101 sum 000101

减法:

    1110  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111

请注意,在使用 2 的补码时,数字左侧的空格对于正数用 0 填充,而对于负数则用 1 填充。 进位总是相加,并且必须是 1 或 0。

干杯

The word complement derives from completeness. In the decimal world the numerals 0 through 9 provide a complement (complete set) of numerals or numeric symbols to express all decimal numbers. In the binary world the numerals 0 and 1 provide a complement of numerals to express all binary numbers. In fact The symbols 0 and 1 must be used to represent everything (text, images, etc) as well as positive (0) and negative (1).
In our world the blank space to the left of number is considered as zero:

                  35=035=000000035.

In a computer storage location there is no blank space. All bits (binary digits) must be either 0 or 1. To efficiently use memory numbers may be stored as 8 bit, 16 bit, 32 bit, 64 bit, 128 bit representations. When a number that is stored as an 8 bit number is transferred to a 16 bit location the sign and magnitude (absolute value) must remain the same. Both 1's complement and 2's complement representations facilitate this.
As a noun:
Both 1's complement and 2's complement are binary representations of signed quantities where the most significant bit (the one on the left) is the sign bit. 0 is for positive and 1 is for negative.
2s complement does not mean negative. It means a signed quantity. As in decimal the magnitude is represented as the positive quantity. The structure uses sign extension to preserve the quantity when promoting to a register [] with more bits:

       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)

As a verb:
2's complement means to negate. It does not mean make negative. It means if negative make positive; if positive make negative. The magnitude is the absolute value:

        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a

This ability allows efficient binary subtraction using negate then add.
a - b = a + (-b)

The official way to take the 1's complement is for each digit subtract its value from 1.

        1'scomp(0101) = 1010.

This is the same as flipping or inverting each bit individually. This results in a negative zero which is not well loved so adding one to te 1's complement gets rid of the problem.
To negate or take the 2s complement first take the 1s complement then add 1.

        Example 1                             Example 2
         0101  --original number              1101
         1's comp  1010                       0010
         add 1     0001                       0001
         2's comp  1011  --negated number     0011

In the examples the negation works as well with sign extended numbers.

Adding:
1110 Carry 111110 Carry
0110 is the same as 000110
1111 111111
sum 0101 sum 000101

SUbtracting:

    1110  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111

Notice that when working with 2's complement, blank space to the left of the number is filled with zeros for positive numbers butis filled with ones for negative numbers. The carry is always added and must be either a 1 or 0.

Cheers

天涯离梦残月幽梦 2024-08-01 12:02:35

2 的补码本质上是一种得出二进制数的加法逆元的方法。 问问自己:给定一个二进制形式的数字(存在于固定长度的内存位置),当将什么位模式添加到原始数字(位于固定长度的内存位置)时,会使结果全为零? (在相同的固定长度存储位置)。 如果我们能想出这个位模式,那么该位模式将是原始数字的 -ve 表示(加法逆); 因为根据定义,将数字添加到其加法逆元总是会导致零。 示例:取 5,它是单个 8 位字节中存在的 101。 现在的任务是想出一个位模式,当添加到给定的位模式(00000101)时,将导致用于保存该 5 的内存位置全为零,即所有 8 位该字节应该为零。 为此,从 101 的最右边的位开始,对于每个单独的位,再次询问相同的问题:我应该将哪一位添加到当前位以使结果为零? 考虑到通常的结转,继续这样做。 当我们处理完最右边的 3 个位置(定义原始数字的数字,不考虑前导零)后,最后一个进位将采用加法逆元的位模式。 此外,由于我们将原始数字保存在单个 8 位字节中,因此加法逆元中的所有其他前导位也应该为 1,以便(这很重要)当计算机添加“数字”(使用 8 表示)时位模式)及其使用“该”存储类型(字节)的加法逆,该字节中的结果将全为零。

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0

2's complement is essentially a way of coming up with the additive inverse of a binary number. Ask yourself this: Given a number in binary form (present at a fixed length memory location), what bit pattern, when added to the original number (at the fixed length memory location), would make the result all zeros ? (at the same fixed length memory location). If we could come up with this bit pattern then that bit pattern would be the -ve representation (additive inverse) of the original number; as by definition adding a number to its additive inverse always results in zero. Example: take 5 which is 101 present inside a single 8 bit byte. Now the task is to come up with a bit pattern which when added to the given bit pattern (00000101) would result in all zeros at the memory location which is used to hold this 5 i.e. all 8 bits of the byte should be zero. To do that, start from the right most bit of 101 and for each individual bit, again ask the same question: What bit should I add to the current bit to make the result zero ? continue doing that taking in account the usual carry over. After we are done with the 3 right most places (the digits that define the original number without regard to the leading zeros) the last carry goes in the bit pattern of the additive inverse. Furthermore, since we are holding in the original number in a single 8 bit byte, all other leading bits in the additive inverse should also be 1's so that (and this is important) when the computer adds "the number" (represented using the 8 bit pattern) and its additive inverse using "that" storage type (a byte) the result in that byte would be all zeros.

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0
朮生 2024-08-01 12:02:35

我喜欢拉维尼奥的答案,但移位会增加一些复杂性。 通常可以选择在尊重符号位或不尊重符号位的情况下移动位。 这是将数字视为有符号数字(半字节为 -8 到 7,字节为 -128 到 127)或全范围无符号数字(半字节为 0 到 15,字节为 0 到 255)之间的选择。

I liked lavinio's answer, but shifting bits adds some complexity. Often there's a choice of moving bits while respecting the sign bit or while not respecting the sign bit. This is the choice between treating the numbers as signed (-8 to 7 for a nibble, -128 to 127 for bytes) or full-range unsigned numbers (0 to 15 for nibbles, 0 to 255 for bytes).

浅语花开 2024-08-01 12:02:35

这是一种对负整数进行编码的巧妙方法,即为负整数保留大约一半的数据类型位组合,并且将大多数负整数与其相应的正整数相加会导致进位溢出这使得结果为二进制零。

因此,在 2 的补码中,如果 1 为 0x0001,则 -1 为 0x1111,因为这将导致总和为 0x0000(溢出为 1)。

It is a clever means of encoding negative integers in such a way that approximately half of the combination of bits of a data type are reserved for negative integers, and the addition of most of the negative integers with their corresponding positive integers results in a carry overflow that leaves the result to be binary zero.

So, in 2's complement if one is 0x0001 then -1 is 0x1111, because that will result in a combined sum of 0x0000 (with an overflow of 1).

初熏 2024-08-01 12:02:35

2 的补码:当我们将一个数的 1 的补码加上一个额外的 1 时,我们将得到 2 的补码。 例如:100101,1的补码是011010,2的补码是011010+1 = 011011(1的补码加1)了解更多信息
这篇文章用图解的方式解释了它。

2’s Complements: When we add an extra one with the 1’s complements of a number we will get the 2’s complements. For example: 100101 it’s 1’s complement is 011010 and 2’s complement is 011010+1 = 011011 (By adding one with 1's complement) For more information
this article explain it graphically.

空袭的梦i 2024-08-01 12:02:35

二进制补码是表示负数的方式之一,并且大多数控制器和处理器以二进制补码形式存储负数。

Two's complement is one of the ways of expressing a negative number and most of the controllers and processors store a negative number in two's complement form.

情释 2024-08-01 12:02:35

使用二进制补码主要出于以下原因:

  1. 避免 0 的多重表示
  2. 避免在溢出时跟踪进位位(如在补码中)。
  3. 执行加法和减法等简单运算变得很容易。

Two's complement is mainly used for the following reasons:

  1. To avoid multiple representations of 0
  2. To avoid keeping track of carry bit (as in one's complement) in case of an overflow.
  3. Carrying out simple operations like addition and subtraction becomes easy.
独孤求败 2024-08-01 12:02:35

简单来说,二进制补码是一种在计算机内存中存储负数的方法。 而正数存储为普通二进制数

让我们考虑这个例子,

计算机使用二进制数字系统来表示任何数字。

x = 5;

这表示为0101

x = -5;

当计算机遇到-符号时,它会计算其二进制补码并存储它。

即,5 = 0101,其二进制补码为1011

计算机处理数字的重要规则是,

  1. 如果第一位是1,那么它一定是数。
  2. 如果除了第一位之外的所有位都是0,则它是正数,因为数字系统中没有-01000不是-0 code> 相反,它是正 8)。
  3. 如果所有位都是0,那么它就是0
  4. 否则它是一个正数

In simple terms, two's complement is a way to store negative numbers in computer memory. Whereas positive numbers are stored as a normal binary number.

Let's consider this example,

The computer uses the binary number system to represent any number.

x = 5;

This is represented as 0101.

x = -5;

When the computer encounters the - sign, it computes its two's complement and stores it.

That is, 5 = 0101 and its two's complement is 1011.

The important rules the computer uses to process numbers are,

  1. If the first bit is 1 then it must be a negative number.
  2. If all the bits except first bit are 0 then it is a positive number, because there is no -0 in number system (1000 is not -0 instead it is positive 8).
  3. If all the bits are 0 then it is 0.
  4. Else it is a positive number.
み零 2024-08-01 12:02:35

对一个数进行按位求补就是翻转其中的所有位。 为了对其进行补码,我们翻转所有位并加一。

使用有符号整数的 2 补码表示,我们应用 2 补码运算将正数转换为其等价负数,反之亦然。 因此,以半字节为例,0001 (1) 变为 1111 (-1),并再次应用该操作,返回 0001

零运算的行为有利于给出零的单一表示,而无需对正零和负零进行特殊处理。 00001111 互补,即加 1。 溢出到 0000,给我们一个零,而不是一个正数和一个负数。

这种表示法的一个关键优点是,无符号整数的标准加法电路在应用于它们时会产生正确的结果。 例如,在半字节中添加 1 和 -1:0001 + 1111,这些位会溢出寄存器,留下 0000

为了进行温和的介绍,精彩的 Computerphile 制作了有关该主题的视频

To bitwise complement a number is to flip all the bits in it. To two’s complement it, we flip all the bits and add one.

Using 2’s complement representation for signed integers, we apply the 2’s complement operation to convert a positive number to its negative equivalent and vice versa. So using nibbles for an example, 0001 (1) becomes 1111 (-1) and applying the op again, returns to 0001.

The behaviour of the operation at zero is advantageous in giving a single representation for zero without special handling of positive and negative zeroes. 0000 complements to 1111, which when 1 is added. overflows to 0000, giving us one zero, rather than a positive and a negative one.

A key advantage of this representation is that the standard addition circuits for unsigned integers produce correct results when applied to them. For example adding 1 and -1 in nibbles: 0001 + 1111, the bits overflow out of the register, leaving behind 0000.

For a gentle introduction, the wonderful Computerphile have produced a video on the subject.

强者自强 2024-08-01 12:02:35

问题是“什么是‘二进制补码’?”

对于那些想要从理论上理解它的人(以及我寻求补充其他更实际的答案)的简单答案:2的补码是对偶系统中负整数的表示,不需要额外的字符,例如+和-。

The question is 'What is “two's complement”?'

The simple answer for those wanting to understand it theoretically (and me seeking to complement the other more practical answers): 2's complement is the representation for negative integers in the dual system that does not require additional characters, such as + and -.

oО清风挽发oО 2024-08-01 12:02:35

给定数字的补码是用 个补码 加上 1 得到的数字的号码。

假设我们有一个二进制数: 10111001101

它的 1 的补码是: 01000110010

它的 2 的补码是: 01000110011

Two's complement of a given number is the number got by adding 1 with the ones' complement of the number.

Suppose, we have a binary number: 10111001101

Its 1's complement is: 01000110010

And its two's complement will be: 01000110011

苄①跕圉湢 2024-08-01 12:02:35

参考:二进制补码 (Thomas Finley)

我反转所有位并添加 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;

Reference: Two's Complement (Thomas Finley)

I invert all the bits and add 1. Programmatically:

  // 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;
烟─花易冷 2024-08-01 12:02:35

我读过的所有内容都没有让我明白

正数从 1 开始,然后递增。 负数从顶部开始向下。

仅此而已。 没有什么需要理解的了。 剩下的只是数学和硬件。

这个系统的优点(对于有限的数字):加法有效。 +1 加 -1 = 0

这是一个有限位数字(8 位、16 位、32 位等)的系统,因为负数开始的地方必须有一个“顶部”,而且加法有时会生成一个 '进出下一列,或者从下一列进出,当没有下一列进出时,它会被神奇地丢弃。

16 位十六进制:正数从 1 开始,一直到 0x7FFF。 负数从 0xFFFF 开始,一直到 8000。

4 位二进制:正数从 0001 开始,一直到 0111。负数从 1111 开始,一直到 1000

3 位二进制,负数:

111 = -1
110 = -2
101 = -3
100 = -4

加法示例:

11+01 = 100 = 00 (2 bit answer)
110 + 001 = 111 (3 bits: -2 + 1 = -1)
111 + 011 = 1010 = 010 (3 bits: -1+3 = 2)

您可以计算如果您愿意,可以使用数字的二进制补码(补码 + 1),但您不必这样做来使用二进制补码,就像使用正数一样:您可以学习使用相同的表示形式就像你对正数所做的那样。 1 为正数。 11111111 是负数。 FFFF 是负数。 FFFE 为负数 2。FFFD 为负数 3。

您有时会看到对二进制补码的解释为“避免零表示的问题”,但这实际上只是硬件设计者使用二进制补码原因的一个特例:加法就可以了。

除了“从顶部开始向下”之外,还有其他表示负数的方法。 我还使用过有两个符号位或两个独立寄存器的系统,一个用于 + 数字,一个用于 - 数字,或者符号位代表单侧向上计数 ADC 前面的反相器的状态。 当人们第一次开始设计计算机硬件时,并不清楚“从顶部开始倒数”是否是负数的最佳表示。 但它使加法变得容易,这是一个胜利者。

everything I've read hasn't brought the picture together for me

Positive numbers start at 1 and work up. Negative numbers start at the top and work down.

That's all. Nothing left to understand. The rest is just math and hardware.

Beauty of this system (for bit limited numbers): addition works. +1 plus -1 = zero

It's a system for bit-limited numbers (8 bit, 16 bit, 32 bit, whatever) because there has to be a "top" for where negative numbers start, and because the addition sometimes generates a 'carry' into or from the next column, which is magically discarded when there is no next column to carry into or out of.

16 bit Hex: Positive number start at 1 and work up to 0x7FFF. Negative numbers start at 0xFFFF and work down to to 8000.

4 bit binary: positive numbers start at 0001 and work up to 0111. Negative numbers start at 1111 and work down to 1000

3 bit binary, negative numbers:

111 = -1
110 = -2
101 = -3
100 = -4

Addition examples:

11+01 = 100 = 00 (2 bit answer)
110 + 001 = 111 (3 bits: -2 + 1 = -1)
111 + 011 = 1010 = 010 (3 bits: -1+3 = 2)

You can calculate the two's complement of a number (complement + 1) if you want to, but you don't have to do that to use two's complement, any more than you have to for positive numbers: you can just learn to use the representation the same way as you do for positive numbers. 1 is positive one. 11111111 is negative one. FFFF is negative one. FFFE is negative 2. FFFD is negative 3.

You sometimes see explanations of two's complement as "avoiding the problem of zero representation" but that's actually just a special case of the reason hardware designers use two's complement: addition just works.

There are other methods of representing negative numbers, other than just "starts at the top and works down". I've also used systems where there are two sign bits, or two separate registers, one for + numbers and one for - numbers, or where the sign bit represents the state of an inverter in front of a single-sided counting-up ADC. When people first started designing computer hardware, it wasn't clear that "starting at the top and counting down" would be the best representation for negative numbers. But it makes addition easy, and that's a winner.

你又不是我 2024-08-01 12:02:35

最简单的答案:

1111 + 1 = (1)0000。 所以1111一定是-1。 那么-1 + 1 = 0。

对我来说理解这些都是完美的。

The simplest answer:

1111 + 1 = (1)0000. So 1111 must be -1. Then -1 + 1 = 0.

It's perfect to understand these all for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文