首先介紹下負數在計算機中的表示和存儲
在計算機系統中,數值一律用補碼錶示和存儲。含符號位和數值位,符號位: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。