位運算判斷兩個數是否異號

首先介紹下負數在計算機中的表示和存儲

在計算機系統中,數值一律用補碼錶示和存儲。含符號位和數值位,符號位:0表示“正”; 1表示“負”。
正數的補碼 = 原碼
負數的補碼 = 負數的原碼取反(符號位保持不變)+ 1
列如
比如 -7 補=11111001(八位二進制) :
原碼:(符號位不變) 10000111
反碼:(符號位不變) 11111000
(符號位不變)加1得補碼:11111001
爲什麼要使用補碼的形式呢?
例如在減法運算中,可以看作是正數和負數的加法操作,使用補碼的形式表示數值,我們就可以直接將x-y表示爲 x + (-y)的處理過程

問題:寫一個函數,判斷給定的兩個數字是否是符號相反的,不可以使用比較運算符。

例如 fun(-1, 100) == true; fun(5,6)=false; fun(-1,-2)=false; 同時,規定0屬於正數。
在二進制表示中,最高位是1的話,就是負數。最高位爲0則爲正數。
因此我可以想辦法通過位運算來判斷。1 ^ 0 = 1。所以 負數^正數=負數。其實就是類似於乘法了。


bool oppositeSigns(int x, int y)
{
    return ((x ^ y) < 0);
}
 
int main()
{
    int x = 100, y = -100;
    if (oppositeSigns(x, y) == true)
       printf ("Signs are opposite");
    else
      printf ("Signs are not opposite");
    return 0;
}
int x = -1, y = 2;
bool f = ((x ^ y) < 0); // true    ⇒ 1 ^ 0 ==  1   < 0   // 負數小於 0  異號

int x = 3, y = 2;
bool f = ((x ^ y) < 0); // false   => 0 ^ 0 == 0 // 0 爲正數   同號

但是,這裏用到了比較運算符。其實完全可以把 <0 的比較去掉,因爲我們只需要知道第一位符號位即可。

bool oppositeSigns(int x, int y)
{
    return ((x ^ y) >> 31);
}

右移31位,則只剩下最高位符號位,不是0,就是1。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章