Nand2tetris中的减法实现

时间:2019-04-20 10:51:17

标签: bit-manipulation nand2tetris

我目前正在通过Nand2tetris上大学课程,这很简单。但是alu可以一步一步进行减法运算,我绝对不知道它是如何工作的。

case class Bet(betId: Option[BetId], stake: BigDecimal, name: String)

case class BetId(betId: String) extends AnyVal

我在网上找不到任何解释。并且即使quickcheck说的是正确的,尝试推导出自己的最后一步看起来也是胡说八道:

opMinus = addition <> notX <> notOut

最后一步感觉就像依赖

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

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

3 个答案:

答案 0 :(得分:1)

对于那些对此知之甚少的人,我看不到很好的解释,所以我会尽力向您解释项目书告诉您的内容。

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

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

这意味着!b =-(b)。因此,如果b = 127,!b =-(127 + 1)= -128。要对此进行更正,请在!b中 1以获取正确的值-127。现在我们已经达到了要减去的正确数字,因此我们可以继续将 b到a(我们要从中减去 的数字)。如果a = 1且b = 127,则如果我们做+!(b)+1,则结果为-126,因为1 +(-128)+1 = 2-128 = -126。

另外,请注意,虽然我使用过!为了表示NOT,实际的按位运算是〜。这被称为2的称赞,您可以在此处阅读有关此内容的更多信息:https://en.wikipedia.org/wiki/Two%27s_complement

编辑:删除了一个错误。

答案 1 :(得分: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)

答案 2 :(得分:0)

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

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