<本站文本内容除另有声明外,转载时均必须注明出处。(详情…中文Minecraft Wiki是完全公开的。请勇于扩充与修正内容!Minecraft中文Wiki微博正在更新!或许有兴趣去看看想与其他用户进行编辑上的沟通?社区专页正是为此创建的。翻译或创建页面之前,不妨看看译名标准化Wiki条例页面。需要管理员的协助?在管理员告示板留言也许可以帮到您。>

教程/算术逻辑

来自Minecraft Wiki
跳转至: 导航搜索
Mcredstonesim icon.png
此条目利用红石模拟器(MCRedstoneSim)格式的图表以求表述紧凑明晰。

有些设计的高度超过了两格,此处使用GIF动态图像逐帧或者多幅图表并列展示。完整图例请见红石图例页面。

Cleanup.svg
该文章需要整理以符合样式标准讨论

请帮助优化文章样式来让它符合样式要求。


加法器[编辑 | 编辑源代码]

第一个版本[编辑 | 编辑源代码]

全加器的游戏截图
全加器

一个全加器接受两个输入位A、B以及一个来自低位的进位,并输出一位和以及向高位的进位。它依赖于2个异或门,2个与门和1个或门。经过一些方面的考虑后,这些逻辑门结构可以被压缩

如图,A、B是两个输入位且C'是来自低位的进位。它产生一个和(S)以及向高位的进位(C)。当多个全加器单元连接在一起时,将下一个全加器的C'和当前全加器的C连接起来,以便产生的进位能够向高位传递。

半加器

半加器和全加器几乎相同,但没有第二个异或门并且直接从第一个异或门输出和(S)。它没有来自低位的进位(C'),但向高位的进位(C)仍然在第一个异或门顶端且向第一个全加器产生一个进位。有的运算器不使用半加器作为第一位,以支持增量(允许向第一位进位)。

单列版加法器[编辑 | 编辑源代码]

全加器
2格宽全加器的游戏截图

这种全加器相似于上面的那种,除了事实上它两格宽且易于对齐。这样的设计对于最小化水平空间是相当有用的,而且可以被成列地建造并接入两条红石总线,消除因扩张总线以接入扩大规模的加法器(的要求)致浪费的空间。

第二个版本[编辑 | 编辑源代码]

全加器

使用的逻辑门:同或门(2),蕴涵门,非门,或门,与门

尺寸:6×12×5(包括输入输出信号占用的空间)

这个加法器将取2个输入位A、B和1个低位的进位C(事实上是C的否定C而并非是C,即示意图中Layer 1左下角红石端的信号值)并将它们相加,产生一个和位(S)和一个向高位的进位(这里同样是C的否定C而并非是C)。

使用上述的逻辑门时,请注意输入和输出。您可能想知道为什么有那么多反相的信号位用以代替常规的信号位。

上述加法器使用了同或门而不是异或门,因为这样设计更加紧凑。同理,我们使用蕴含门来代替与门,这样能够更加紧凑。

因此对于(结构)最紧凑的加法器,必然要使用反相的信号。这些加法器太复杂,很难用(每格可以容纳2层的)平面图来表示,所以将每一层都单独表示为一张示意图以使建造过程更加清晰易懂。

半加器

使用的逻辑门:同或门,蕴含门

尺寸:5×4×4

这个加法器将2个输入位相加得到结果作为和输出(S)。如果2个输入位的信号值都是1,进位C将会得到1(C将会是0)。可以对这个半加器进行修改来获得一个非反相的输出C,但使用这个半加器才能作为一个全加器链(多位全加器)的起始部分。

拓展: 对于刚接触红石的人来说,这样更容易理解:我们说输出位C有一个非门将信号反相并连接到一个铁门、活塞门之类的门,输出位S连接到一些粘性活塞来控制地面陷阱。假设有一个1×1×1的方块不受粘性活塞影响,称之为安全方块。当输入位A有红石信号时,门打开的同时,地面也会打开,如果你站在安全方块上,你就不会掉下去。输入位B只控制地面,但如果输入位A有红石信号,则输入位B会同时控制这二者。(同理)当两个输入位都有红石信号时,输入位A只控制地面。这意味着如果你离开服务器的时候不想让任何人进来,你可以给输入位A和B加上红石信号,当其他人移除输入位A的红石信号时,地面会打开,但门依然是关闭的。即使他们知道这个秘密也仍然不能进来。

第三个版本[编辑 | 编辑源代码]

全加器

尺寸:5×6×3

每位进位都是相互对齐的,这样可以方便地串联这些子模块。

快速加法器[编辑 | 编辑源代码]

当建造高级数字电路比如计算机和乘法器时,使用的加法器必须尽可能地快,以确保最大的运行速度。简单的加法器存在一个基本的速度问题,许多加法器设计都尝试改善这一问题。这个问题是进位传播的延迟,这是由加法器的进位方式所引起的延迟。我们可以看如下的1111 + 0001的例子:

1111
0001
----
1110

这是加法运算过程的第一步,对两个输入异或。由于最低有效位有两个1,这会触发与门产生进位并送往高位:

  1
1111
0001
----
1100

此时就产生了问题:由于待进位的当前位上仍然有两个1,所以会再次触发向高位的进位。这是通过将第一个半加器的输出与低位的进位相加来完成的,这里存在很大的问题,因为接下来你将反复产生向高位的进位直到越过最高位。如果每个与门产生2刻的延迟,为了计算最后一步中需要相加的所有进位,总共需要2刻×4,即8刻的时间。

如果现在你要计算999+1,你不会有“9 + 1 = 10,进位1,所以9 + 1 = 10,进位1,所以9 + 1 = 10,得到1000”这种闲得无聊的想法。在高级电路中同样也是如此。

真正的电路工程师和有创造力的红石玩家已经设计出了计算进位比这种串行方式更高效的电路。

顺便提一下,以这种串行方式计算进位的加法器被称为行波进位加法器

活塞加法器[编辑 | 编辑源代码]

解决行波进位存在的问题的最简单、最经典的方法之一是使用带活塞的即时与门。这种加法器简单快速,但由于使用活塞导致电路不稳定,当方块因意外而掉落时,整个电路就被破坏了。活塞也存在时钟同步上可能难以忍受的不便之处,在建造高级电路时可能会对(整个装置)的同步时钟产生严重依赖性。

PistonANDgates.png

每当产生进位时,其将会通过带拉杆的红石线路传送,而不是与门。活塞收缩,进位C被送到高位,这一过程完全没有产生进位传播的延迟(直到信号强度耗尽)。

下面这个视频展示了这种逻辑的一个简单实现。这种设计庞大而且分散,容易看到每一个单独的加法器部分以及进位逻辑。


4位加法器[编辑 | 编辑源代码]

使用的逻辑门:同或门(7),蕴含门(4)非门(4),或门(3),与门(3)

尺寸:23×12×5

注意!最低有效位(个位)在图的左边,这样可以更清楚地看到从半加器到全加器的过程。如果想要通常的从左向右的输入,请翻转示意图。

这个加法器将第2、第4位的输入位(A和B)相加,每加1位产生一个和(S)以及一个进位(C)。和的顺序与输入位顺序相同,这意味着图中最左边的输出位S代表结果的最低有效位。这是一个多位加法器的例子;加法器可以通过这种方式串联起来以计算更多位数的数字。

交替式4位加法器[编辑 | 编辑源代码]

功能相同但设计不同,使用4个全加器而不是1个半加器和3个全加器。

注意:开关为输入位A和B(顶部为低位进位C)。

减法器[编辑 | 编辑源代码]

减法和加法的道理是一样的,例如,3 - 2 = 3 + (-2) = 1。因为我们已经有了加法计算的框架,只需要添加一个负号就可以简单地得到结果。问题在于如何表示这个负数。

我们对小学减法中向高位借位的概念很熟悉,比如这样:

 5623
- 128
-----

我们没有办法用3减去8,所以我们从高一位借了1以通过13减8代替(结果显然是5)。

   1
 5623
- 128
-----
    5

然而计算机是没法做这种考虑的,所以当计算机找到一个负数时,它不会也不能在前面硬添一个负号。它只会像如下这样从高位进行"借位"相减:

 000000
 -    3
-------
-999997

这在二进制中同样适用。让我们用一个4位二进制数作为例子:

   1      11     111    1111
 0000    0000    0000    0000
-0011   -0011   -0011   -0011
-----   -----   -----   -----
-   1   -  01   - 101   -1101

我们可以按照这个方式一直反复计算下去,但这并没有什么用。这就体现了4位寄存器的作用:它将在接收到4位数据后截断(抛弃其他数据)。因此,在我们截断这个数字之后(在这个例子中已经得到了体现,否则最后结果的左边会有无穷多个1),多亏这个小技巧,我们可以对这4位数据之外的0做任何想做的事情,包括在它们之前添一个1(这将在之后被证明是非常有用的)。

10000
-0011
-----
 1101 <-- 注意:这个数字是正数!成功!

还记得我们说过我们的红石没有特别的方法来区分正数和负数吗?我们只是创造了一种区分的方式:如果数字的符号位(最高位)是1,那么它就是一个负数。这种利用在二进制数中的小技巧其实是一套名为“二进制补码”的理论。

二进制补码的正式定义是:

一个负数b的补码等于2 ^ (n+1) - b,其中n是b的位数。

本质上说,-b的补码就是将b的补码的各位取反(用1替换0,用0替换1)再加1。

我们所做的是将最高位变成一个"负号"(如果它是1),但如果你一直在阅读这个页面,你会意识到这没有那么简单。通常把带有这种符号标识位的数字称为带符号的整数。 在普通的加法器中,这种二进制补码规则并不生效,这种数字称为无符号的整数。无符号的数字可以比带符号的数字取到更大的值,但不能比0小;带符号的数字最大只能取到无符号数字所能取到的大约一半,但可以比0小。 这意味着这两种数字有相同长度的取值范围,但取值区间的位置不同,比如下面的8位整数的例子:

无符号: 0 - 255
带符号:-128 - 127

应当注意的是,当使用最小的有符号数(在上面的例子中是-128)时,可能会出现一些匪夷所思的问题,所以应该避免这种情况。

现在我们有了一种用正的值来表示负数的方法,将它运用到加法器中就很简单了。目前我们可以计算

A + B

我们要计算的是

A - B

A + (-B)

所以,只要我们输入B的补码,加法器就变成了减法器。通过使用符号位(最高位)作为进位的1,这很容易实现。剩下的就是如何对B求补码。

在实现此功能时需要注意一件重要的事情:因为得到的结果依然是二进制补码,所以存在减去符号位的问题,因此要倒过来减。这个问题通常由最高位的加法器来处理。

这都可以实现到一个加法器中:

Addsub.jpg

电路中加入了一个控制位,当它被通入红石信号时,就会变成一个减法器,当没有红石信号时则是一个加法器。此外,在控制位和输入B的每一位之间都增加了一个异或门,将每个异或门的输出作为每个加法器单元真正的输入位B。最后,为了使二进制补码单元兼容,需要在控制位和符号位上添加最后一个异或门。

这是在CPU中实现负数和减法的最简单方法,因为它可以优雅地进行加法运算并将结果存储在寄存器中。如果需要在计算器中实现这种操作,只需要将输出结果减1,然后将符号位之外的每一位取反。如果数字是负数,只需要将符号位设为1即可。

为了建造一个减法器,只需要对其中一个输入按位取反即可。如果这个数是负数,那么结果也是相反的。在实际的计算机中,符号位决定数字的正负性,如果将它也纳入考虑(应用相同的取反规则),你可以判断出这到底是一个负数,还是仅仅是一个较大的数字。

逻辑单元[编辑 | 编辑源代码]

在电路中使用一个逻辑单元可能是有用的。逻辑单元会根据控制信号来决定输出哪种操作的结果。这样的逻辑单元可以使用在更加复杂的电路中,比如ALU(算术逻辑单元)。

这是一个2位逻辑单元的例子,它的控制信号有4种状态。

Logic unit.gif

它的输出在最上面一行,从左到右依次通过输入11、00、01和10来触发(输入在左边,上面是低位,下面是高位)

以下是另一个使用格雷码的简化版本,输出体现在最上面一行红石火把的亮灭。这种设计可以扩展到任意的位数,但考虑到时间效率的问题,一般不会超过1个字节(8位)。输出从左到右依次通过输入11、01、00、10来触发。

Logic unit 3.gif

算术逻辑单元(ALU)[编辑 | 编辑源代码]

ALUwikipedia.png

算术逻辑单元(ALU)是CPU的核心部分。它进行计算和逻辑处理,然后将结果传递给寄存器。ALU根据输入来选择一个特定的运算操作,执行它,然后给出结果。

下图显示的ALU是一个1位的ALU,可以执行下列运算:ADD(求和),AND(求与),XOR(求异或)。它接收输入A和B,然后执行所选择的运算操作。阅读加法器以了解ADD运算是如何工作的。XOR和AND运算是在逻辑电路页面上所介绍的基本功能。

可以向ALU中添加更多的运算操作,比如乘法,除法,OR(求或),NAND(求与非)等等,这些运算都可以通过对ALU进行一定的修改来加入到其中。

这样的1位ALU可以相互连接起来以形成多位的ALU。就像加法器一样,把示意图中的C out端连接到另一个ALU的C in端即可。