8 / 37 · 概念
二補數、符號擴展與溢位
透過公式與反例,區分位元序列的 signed 解讀與加法溢位條件。
單元可免費閱讀,註冊課程即可儲存學習進度。
最高有效位元的權重改變了
位元二補數二補數以固定寬度的位元序列表示帶符號整數。n 位元範圍為 −2^(n−1) 至 2^(n−1)−1。整數解讀如下。
4 位元 1010 以 unsigned無符號(unsigned)將位元序列解讀為非負整數。n 位元範圍為 0 至 2^n−1;相同位元序列的帶符號解讀可能得到不同數值。 詳細內容 解讀為 10,以 signed 解讀為 −6;不是把符號位元拿掉,再將其餘部分當成絕對值。固定寬度下, 可由位元反相反相是將 0 變為 1、1 變為 0 的 NOT 運算。公式上方的橫線表示對線下的整個運算式套用 NOT。 詳細內容再加 1 得到,但最小值 −8 對應的正數 +8 不在同樣的 4 位元 signed 範圍內。
擴展必須保留數值
unsigned 擴展在前方補 0,signed 擴展則補原本的符號位元。1010 變成 00001010 是 +10,變成 11111010 才是 −6。即使擴展相同位元,解讀方式不同,所需電路也不同。
logic signed [3:0] a, b;
logic signed [4:0] exact;
logic [3:0] result;
logic overflow;
assign exact = {a[3], a} + {b[3], b};
assign result = exact[3:0];
assign overflow = (a[3] == b[3]) && (result[3] != a[3]);本例是兩個運算元、無 carry 輸入的 signed 加法。將 5 位元總和保留在 exact,再檢查縮窄結果的符號是否正確。
起始值設為 11111010。請確認 unsigned 250 與 signed −6 是同一位元序列;改變 b7 時,兩種解讀的數值會往不同方向變化。
11111010 → unsigned 250 · signed -6 · hex 0xFA
Carry 與 signed overflow 不同
相同符號的數相加,結果卻變號,就是 overflow。4 位元的 存成 1010,看起來是 −6; 存成 0111,看起來是 +7。兩個異號數相加不會發生這種超出範圍。
混合 signed 與 unsigned 的 RTL 運算式容易使比較、擴展規則混淆。請明確指定兩運算元的寬度與符號性,並將最小值、−1、0、最大值納入邊界測試。
自己試試看
求 4 位元 signed 的 與 所儲存的位元序列及 overflow,並說明 取負的結果。
查看解說
為 1001,沒有 overflow。10 超出範圍,存成 1010(−6),因此發生 overflow。−8 反相加 1 後仍留下 1000,因為同寬度無法表示 +8,不能將其當成正確的絕對值計算。