首先,维基百科文章指出它不能从负符号数否定为有符号数。它们的意思是因为它需要 9 位来表示正 128,而您无法使用 8 位寄存器来做到这一点。如果您要从负符号转换为正无符号转换,那么您有足够的位。当你否定 0x80 时,硬件应该给你 0x80,因为这是正确的答案。
二进制补码中的加法、减法、乘法等加法与小学的十进制数学没有什么不同。您排列二进制数,添加列,该列的结果是最低有效位,其余的将转移到下一列。因此,例如将 0b001 添加到 0b001
1
001
001
===
010
最右列两个1相加,结果为0b10(十进制2),写0后进位一,一加零加零为一,无进位,零加零为零,结果为0b010 .
1 加 1 的最右边一列是 0b10,我们写 0 进位一,那么进位一同时是最右边一列的进位,也是第二列的进位。此外,对于纸笔数学,我们通常只在非零时谈论进位,但如果你仔细想想,你总是会携带一个数字,就像我们的第二列一样,一加零就是一个零。
您可以将二进制补码否定视为反转并加一,或者将位遍历并反转到一个点然后不反转,或者将零的结果减去数字。
您可以使用铅笔和纸在二进制中进行减法计算,但与十进制相比,借用时会让人头疼,但可以。对于您所问的问题,请考虑反转并添加一个。
如果你把它减少到比 8 更少的位,你会更容易理解这一点,3 是一个易于管理的数字,它都是从那里扩展的。
所以下面的第一列是输入,第二列是反转版本,第三列是第二列加一。第四列是 msbit 的进位,第五列是 msbit 的进位。
000 111 000 1 1
001 110 111 0 0
010 101 110 0 0
011 100 101 0 0
100 011 100 1 0
101 010 011 0 0
110 001 010 0 0
111 000 001 0 0
快速了解添加一到两位:
00+1 = 001
01+1 = 010
10+1 = 011
11+1 = 100
对于将数字加一的情况,从第二位执行到第三位的唯一情况是当您的位全为 1 时,其中的单个零会停止级联进位位。因此,在上面的三位反转表中,只有两种情况下您有进位到 msbit 是 111 和 011,因为这是仅有的两种情况下所有低位都已设置。对于 111 情况,msbit 有一个进位和一个进位。对于 011 情况,msbit 有进位但没有进位。
所以正如其他人所说,芯片中连接了晶体管,如果设置了 msbit 进位并且未设置 msbit 进位,则在某处设置一些标志,否则清除标志。
所以请注意,上面的三位示例是按比例缩放的。如果在反转之后并且在添加一个之前,您有 0b01111111 那么您将在没有进位的情况下获得进位。如果您有 0b11111111,那么您将获得进位和进位。请注意,零也是一个数字,当您反转它时,您会得到相同的数字,不同之处在于当这些位被认为是有符号时,在取反时可以表示零,而全零则不能表示 1。
但底线是,这不是危机或世界末日的事情,处理器中有大量的数学和其他操作,其中进位位和有效位从一侧或另一侧脱落并溢出和下溢正在触发,等等。大多数情况下,程序员从不检查这种情况,而这些位只是掉在地板上,有时会导致程序崩溃,或者有时程序员使用 16 位数字进行 8 位数学运算只是为了确保没有什么不好的事情发生,或者出于同样的原因将 8 位数字用于 5 位数学。
请注意,硬件不知道有符号或无符号的加法和减法。硬件也不知道如何减去。硬件加法器是三位加法器(两个操作数和进位),结果和进位。将这些中的 8 根连线,您有一个 8 位加法器或减法器,无进位相加是两个操作数直接连接一个零作为 lsbit 进位。加进位是两个操作数直接连接到连接到lsbit 进位。减法是与第二个操作数反转并在进位位上加一个。至少从高层次的角度来看,这些逻辑都可以得到优化和实现,通常有两种在随意检查时很难理解的方式。
真正有趣的练习是乘法,想想用铅笔和纸做二进制乘法,然后意识到它比十进制容易得多,因为它只是一系列的移位和加法。给定足够的门,您可以将每个结果位表示为一个方程,方程的输入是操作数。这意味着如果您愿意,您可以进行单时钟倍频,在早期,门太多,所以完成了多时钟移位和加法,今天我们烧掉了门并获得单时钟倍频。另请注意,理解这也意味着如果您说 16 位 = 8 位乘以 8 位乘法,则无论是有符号乘法还是无符号乘法,低 8 位结果都是相同的。因为大多数人都会做 int = int * int; 这样的事情。如果您只关心结果位(不检查标志等),您真的不需要有符号或无符号乘法。有趣的东西..