計算機算術
二進位減法
硬體玩了個小魔術:它其實從不真正做減法。ALU 不另外蓋一個用借位的減法器,而是用「a 加上 b 的相反數」來算 a 減 b。它重用做加法的同一個加法器。聰明之處在於如何便宜地取 b 的相反數,答案就是二補數:把 b 的每個位元反相再加 1,就得到同樣位元數下的負 b。
走一遍。要算 a 減 b,ALU 把 a 送進加法器一個輸入、把反相後的 b 送進另一個輸入,再把加法器的進位輸入設為 1——這個進來的 1 正是取相反數裡「加 1」那一步,所以幾乎不花成本。加法器做的是 a + (NOT b) + 1,等於 a + (負 b) = a 減 b。4 位元例子:7 減 5。b = 0b0101,反相成 0b1010,進位輸入設 1。相加 0b0111 + 0b1010 + 1 = 0b0010 = 2。正確。一條控制線(進位輸入)加上 b 上的一排反相器,就把加法器變成加減法器。
這就是二補數無所不在的深層原因。因為減法只是「加上一個取了相反數的運算元」,一份硬體就同時服務兩者,而且零只有一種表示(沒有要特別處理的正零與負零)。誠實的注意點和加法一樣:結果必須放得進字組寬度。減法也會溢位——例如很大的正數減很大的負數可能超出正數範圍——硬體會透過條件旗標示警,而不是悄悄給出亂答案。
用 4 位元算 7 減 5。把 5 取相反數:0b0101 反相成 0b1010,再經由進位輸入加 1。加法器做 0b0111 + 0b1010 + 1 = 0b0010 = 2,原封不動地用加法硬體。
減法 = 加上反相後的運算元並把進位輸入設為 1。不需要借位電路。
減法和加法一樣會溢位。一個常見的意外:把最負的數(例如 8 位元的負 128)取相反數會得回同一個值,因為沒有一個正 128 可以落腳。
又称
另见