0

我目前正在通过 Nand2tetris 为一门大学课程工作,这很简单。但是 alu 可以一步做减法,我完全不明白这是如何工作的。

opMinus = addition <> notX <> notOut

我在网上找不到任何解释。即使 quickcheck 说它是正确的,我自己尝试推导它的最后一步看起来也是无稽之谈:

a - b
a + !b + 1 -- 2s complement
!!(a + !b + 1) -- double negation
!(!a + b) -- apparently this is correct and i have no clue why

最后一步感觉就像它依赖于类似的东西

!(a+b) == !a + !b + 1

但我不知道为什么会这样,因此非常感谢您的解释。谢谢阅读!

4

3 回答 3

1

对于对此了解较少的人,我没有看到很好的解释,所以我会尽力解释项目书告诉你的内容。

由于一些 cpu 实际上有芯片可以接收信号将加法器切换到减法器(更好的说法实际上是它们的晶体管以允许的方式排列)而 nand2tetris 没有,你实际上必须否定你减去的数字(b)。要在二进制文件中执行此操作,您不是它。如果生活很简单,这将是你的最后一步。

然而,以这个为例。假设你正在编程。您正在使用带符号的 8 位 int 来保存值 b。

这意味着!b = -(b)。所以,如果 b=127,!b = -(127+1) = -128。要更正这一点,您1 添加到 !b 以获得正确的值 -127。我们现在处于我们想要减去的正确数字,所以我们可以继续b 添加到 a(我们想要从 中减去的数字。如果 a = 1 且 b = 127,如果我们执行 a + !(b) + 1,结果将是 -126,因为 1 + (-128) + 1 = 2-128 = -126。

另外,请注意,当我使用 ! 表示NOT,实际的按位运算是~。这被称为 2 的恭维,您可以在此处阅读更多相关信息:https ://en.wikipedia.org/wiki/Two%27s_complement

编辑:删除了一个错误。

于 2020-08-08T03:34:14.180 回答
1

一种更直观而不是仅从代数角度看待它的方法是考虑按位补码在整个数轴上的作用,即对称地翻转它。!a + b然后添加b翻转的上下文,最后将!所有内容翻转回来。在翻转的上下文中“向前”一步(so, b = 1)在正常上下文中向后退一步,依此类推。

这种“翻转,动作,翻转”有效地将中间的动作从正常工作的方向转变为正常工作的方向,该原理还有其他实例,例如有时两个参数都翻转了min(a, b) = !max(!a, !b)

于 2019-04-20T11:05:17.453 回答
0

在玩了一些之后,我想通了:

(a-b)
!!(a-b)            | double bitwise not is id
!(!(a-b)+1-1)      | +1-1 is id
!(-(a-b)-1)        | !(a-b)+1 = -(a-b)
!(-a + b - 1)      | distribute the negation
!(!a + 1 + b - 1)  | -a = !a+1
!(!a + b)
于 2019-04-20T11:02:32.850 回答