为什么是补码?
我正在编写一个教程来教孩子们(9 至 13 岁)编程。我从计算机本身开始,它们与计算机科学没有太大关系,更多的是涉及解决计算问题的过程。
以此为出发点,我引导他们认识到机器可以帮助我们解决某些计算问题。人们擅长抽象思维和想象力,但计算机非常擅长遵循明确的例程。他们可以一次又一次地以惊人的速度做到这一点!
我的教程中已经介绍了以二进制格式表示数字。但如何表示负数呢?在任何符号系统中,都有很多方法可以做到这一点,但为计算机选择的系统是出于一个非常具体的原因:减少与有符号整数值相加所涉及的机器数量。我们不想仅仅为了处理负数而构建和构建单独的芯片,我们希望使用我们用于自然数算术的相同芯片!
如果有人在街上问你(这看起来完全不现实)“计算机如何表示负数,为什么要这样表示负数?”
我的具体问题:
计算机如何表示负数?
为什么计算机以这种方式表示负数?
我猜想这么多经验丰富的开发人员必须考虑一下这个问题。有些人甚至可能无法给出答案。我并不是想浮夸,这是来自实际经验,我问过专业开发人员这个问题,他们也无法回答。他们茫然地凝视着。给他们 JBoss 和 JavaBeans,他们就会满怀信心地碾压你。太搞笑了!我也为这个问题而苦苦挣扎,我每次都必须提醒自己答案,并且我需要一张纸或白板来找出解决方案。我希望引导学生更好地了解他们正在使用的机器。
I'm writing a tutorial to teach kids (ages 9 to 13) about programming. I started with computers themselves, they don't have that much to do with computer science, it's more about the process involved with a solution to a computational problem.
With that starting point, I'm guiding them toward an understanding that machines can help us with certain computational problems. People are great at abstract thinking and imagination, but computers are AWESOME at following a well-specified routine. They can do it again and again, at amazing speed!
Representing numbers in binary format has already been covered in my tutorial. But how do you represent negative numbers? There are so many ways to do this, in any notational system, but the system chosen for computers is for a very specific reason: to reduce the amount of machinery involved with adding signed integer values. We don't want to have to construct and build separate chips just to handle negative numbers, we want to use the same chips we have been using for natural number arithmetic!
If someone asked you on the street (as totally unrealistic as this seems) "how do computers represent negative numbers, and why do they represent them this way?"
My specific questions:
How do computers represent negative numbers?
Why do computers represent negative numbers this way?
I would guess that this many experienced developers would have to think about this a bit. Some might not even be able to come up with an answer. I'm not trying to be pompous, this is from actual experience, I've asked professional developers this question and they can't answer it. They draw a blank stare. Give them JBoss and JavaBeans and they will steamroll you with confidence. So funny! I too struggle with this question, I have to remind myself of the answers every time and I need a piece of paper or white board to work out a solution. What I'm hoping is to guide students toward a better understanding of the machine they are working with.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
取正值,反转所有位并加一。
-7 中的 7 相加很容易得出零。位运算速度很快。
如何让它变得简单?
以 7 和 -7 为例。如果将 7 表示为
00000111
,要找到 -7,请反转所有位并加 1:现在您可以添加以下标准数学规则:
对于计算机来说,此操作相对容易,因为它基本上涉及逐位比较比特并携带一个。
如果您将 -7 表示为
10000111
,则这没有意义:要添加它们,您将涉及更复杂的规则,例如分析第一位和转换值。
并且不要忘记@trashgod 所说的,在 2 的补码中只有一个零。要检查它:
不同于
00000000
(0) 等于10000000
(-0< /em>)Take the positive value, invert all bits and add one.
It makes easy to add 7 in -7 and came up with a zero. The bit operations are fast.
How does it make it easy?
Take the 7 and -7 example. If you represent 7 as
00000111
, to find -7 invert all bits and add one:Now you can add following standard math rules:
For the computer this operation is relatively easy, as it involves basically comparing bit by bit and carrying one.
If instead you represented -7 as
10000111
, this won't make sense:To add them, you will involve more complex rules like analyzing the first bit, and transforming the values.
And don't forget what @trashgod said, in 2's complement you have only one zero. To check it:
Differently from
00000000
(0) being equal to10000000
(-0)计算机如何表示负数?
计算机通过使用正常的减法规则计算从零减去该数字所得到的结果来表示负数。也就是说,要找到
-5
在二进制中的样子,您需要从0
(二进制)中减去5
(二进制):..所以
-5
看起来像二进制的1011
。为什么计算机以这种方式表示负数?
因为这样做意味着当计算机进行加减法时,它不必检查其中一些是否为负数:数学无论如何,效果很好。这使得计算机变得更简单,而更简单的计算机的构建成本也更低。
How do computers represent negative numbers?
Computers represent negative numbers by calculating the result that you would get if you subtracted that number from zero, using their normal rules for subtraction. That is, to find what
-5
looks like in binary, you subtract5
(in binary) from0
(in binary):..so
-5
looks like1011
in binary.Why do computers represent negative numbers this way?
Because doing it this way means that when the computer is adding and subtracting numbers, it doesn't have to check if some of them are negative or not: the maths works out anyway. This makes the computer simpler, and simpler computers are cheaper to build.
我能想到的两大原因:
来自维基百科:
Two big reasons I can think of:
From Wikipedia:
写下数轴
-32768... -1, 0, 1, 2, ... 32767
向右添加移动。减法向左移动。概念上很好,但是我们如何表示这个符号呢?
我们可以使用“有符号量值”,其中符号和值是分开的。这会让人感到困惑,因为我们有两条符号不同的平行数轴。
“带符号大小”的替代方法是将每个数字编码为另一个数字。
我们可以为所有数字添加偏移量 32768。新的范围是无符号 0 到 65535。一切仍然有效,对吗?您只需将固定的偏差值应用于所有数字即可。添加向右移动。减法向左移动。 32768可以解码为0。0可以解码为-32768。
这非常有效。对数字进行“编码”只是添加一个偏差。 “解码”一个数字只是减去偏差。
这是另一种编码方案。
将所有负数带到数轴的另一边。
0, 1, 2, ..., 32767, -32768, ... -1
加法仍然向右移动。取任意数字(除了一个例外)。它右边的数字总是更大。
唯一的例外是 32767。它右侧的数字是“溢出”。
减法仍然向左移动。取任意数字(除了一个例外)。左边的数字总是较小。唯一的例外是 -32768。它左边的数字是“下溢”。
编码和解码涉及更多一些。 0 到 32767 有一个简单的编码和解码:什么也不做。这些数字本身被编码。然而,32768 到 65535 是负数的编码。
Write down a number line
-32768... -1, 0, 1, 2, ... 32767
Add moves to the right. Subtract moves to the left. Conceptually nice, but how can we represent the sign?
We can use "signed magnitude" where the sign and the value are separate. This gets confusing because we have two parallel number lines with differing signs.
An alternative to "signed magnitude" is to encode each number as another number.
We can add an offset of 32768 to all the numbers. The new range is the unsigned 0 to 65535. Everything still works, right? You just have a fixed bias value applied to all the numbers. Add moves to the right. Subtract moves to the left. 32768 can be decoded to 0. 0 can be decoded to -32768.
This works perfectly. The "encoding" a number is simply adding a bias. "Decoding" a number simply subtracts the bias.
Here's another encoding scheme.
Carry all the negative numbers over to the other side of the number line.
0, 1, 2, ..., 32767, -32768, ... -1
Addition still moves to the right. Take any number (with one exception). The number to the right of it is always larger.
The one exception is 32767. The number to the right of it is "overflow".
Subtract still moves to the left. Take any number (with one exception). The number to the left is always smaller. The one exception is -32768. The number on the left of it is "underflow".
The encoding and decoding are a little more involved. 0 to 32767 have a trivial encoding and decoding: do nothing. The numbers are encoded as themselves. 32768 to 65535, however, are encodings of negative numbers.
二进制补码用于将加法和减法简化为可由一个硬件单元执行的一次运算。在二进制补码算术中,您不是用一个数字减去另一个数字,而是将一个数字的倒数与另一个数字相加。在过去,拥有一个单独的硬件来进行数字减法是一件非常大的事情,因此提出一个用单个单元执行减法和加法的系统非常有用。
通过翻转位并加一,您可以找到任何二进制补码数的倒数。例如,
-1
在四位实现中将表示如下:您可以通过将两个相加来验证这一点:
但是,我们正在使用四位,因此结果会被截断。我们现在有
0000
或0
。我们添加了一个数字及其负数,结果为零。欢呼!现在,最后一个示例是 4 - 6。4 表示为
0100
。 6 表示为0110
。要得到 -6,请翻转位并加一:1001 + 1 = 1010
。0100 + 1010 = 1110
。1110
是一个负数(所有最高有效位带有1
的数字在二进制补码中都是负数)。为了找出它的绝对值,我们翻转位并加 1。0001 + 1 = 0010
,或 2。因此,加法的结果是-2
。4 - 6 -2
。我们的数学检查出来了。恭喜。你现在和电脑一样聪明。
Two's compliment is used to simplify addition and subtraction into one operation which can be performed by one hardware unit. Instead of subtracting one number from another, in two's compliment arithmetic you add one number's inverse to another. Back in the olden days, having a separate piece of hardware for subtracting numbers would have been a pretty big deal, so coming up with a system to perform subtraction and addition with a single unit was very useful.
You can find the inverse of any number in two's compliment by flipping the bits and adding one. For instance,
-1
would be represented as follows in a four bit implementation:You can verify this by adding the two:
We're working with four bits, however, so the result is truncated. We now have
0000
, or0
. We have added a number and its negative and gotten zero. Hurray!Now, for one final example, let's do 4 - 6. 4 is represented as
0100
. 6 is represented as0110
. To get -6, flip the bits and add one:1001 + 1 = 1010
.0100 + 1010 = 1110
.1110
is a negative number (all numbers with a1
in the most significant digit are negative in two's compliment). To find out its absolute value, we flip the bits and add 1.0001 + 1 = 0010
, or 2. Therefore, the result of our addition is-2
.4 - 6 -2
. Our math checks out.Congratulations. You are now exactly as smart as a computer.
Q1.计算机如何表示负数?
2的赞美方法!
Q2 .为什么计算机以这种方式表示负数?
以下是 2 的补码的工作原理:
对于任何 x,
如您所见,2 的补码是合乎逻辑的且易于实现,并且没有极端情况,这就是为什么它比其他方法更受青睐。
让我们考虑 1 的补足,这是我正在讨论的一种具有极端情况的方法,其中 0 和-0 存在(所有位未设置 = 0,所有位设置 = -0),这意味着要为硬件电路执行更多操作,特别是在数字 x 和 -0 的操作期间。 [维基百科有关于避免负零的很好的例子,你可以看看它们]
我希望这个解释能够安抚您孩子们的心……
Q1. How do computers represent negative numbers?
2's compliment method!
Q2 . Why do computers represent negative numbers this way?
Here's how 2's compliment work:
For any x,
As you can see, 2's compliment is logical and easy to implement and doesn't have corner cases and that is why it is preferred over other methods.
Lets consider 1's compliment , a method with corner cases I was talking about, in which 0 and -0 exist (all bits not set = 0, all bits set = -0) which translates to more operations to perform for the Hardware circuits, especially during operations with a number x and -0. [Wikipedia has nice examples on Avoiding Negative Zero, you can have a look at them]
I hope this explanation soothes the minds of your kids...