程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 不用比較運算符比較兩個數的大小

不用比較運算符比較兩個數的大小

編輯:C++入門知識

紀念一下

不准在函數體中使用任何比較運算,比如if,for, while等,不准調用任何庫函數。

 

 int max(int a,int b)   
{   
    int sa,sb,f; 
    sa=((a/2)&0x80000000)>>31; 
    sb=((b/2)&0x80000000)>>31; 
    f=!(!(a/(b|1))); 
    return (sa^sb)*(a*(!sa)+b*(!sb))+(!(sa^sb))*(a*(sa^f)+b*(!(sa^f))); 
} 

int max(int a,int b) 
{ 
    int sa,sb,f;
 sa=((a/2)&0x80000000)>>31;
 sb=((b/2)&0x80000000)>>31;
 f=!(!(a/(b|1)));
 return (sa^sb)*(a*(!sa)+b*(!sb))+(!(sa^sb))*(a*(sa^f)+b*(!(sa^f)));
}

解釋:

((a/2)&0x80000000)>>31; //取得a的符號位

((b/2)&0x80000000)>>31; //取得b的符號位

unsigned 和 signed 會對負數效果有影響,當時沒有考慮到這點,只是按題目要求以無符號數處理了

除以2之後無符號數,最高位會變成0,而有符號數,依舊帶符號。

 


!(!(a/(b|1)));//a和b的大小標志位


a/b時,當a大,則為一個非0數,否則為0,但當b=0時計算無法進行

所以把b的最低位置1,保證計算能夠進行下去。雖然置1會讓低位為0的數增加1但僅對結果不會產生影響。

兩次取反只是為了保證結果為1和0而不是其他數

 


剩下來的就是邏輯運算的選擇性輸出了

a符號位記作Sa

b符號位記作Sb

ab結果比較位記作f

共有六種情況

Sa<Sb a是正數,b是負數

Sa>Sb a是負數,b是正數

Sa=Sb ab同符號

  Sa=0 同為正數

  Sa=1 同為負數

Sa<Sb,Sa=Sb且Sa=0且f=1,Sa=Sb且Sa=1且f=0 這三種情況時a大

Sa>Sb,Sa=Sb且Sa=0且f=0,Sa=Sb且Sa=1且f=1 這三種情況時b大

組合輸出結果 (Sa^Sb)*(a*(!Sa)+b*(!Sb))+(!(Sa^Sb))*(a*(Sa^f)+b*(!(Sa^f)));

去掉中間變量就成這樣子了。


 

 int max(int a,int b)   
{   
  return ((((a/2)&0x80000000)>>31)^(((b/2)&0x80000000)>>31))*(a*(!(((a/2)&0x80000000)>>31))+b*(!(((b/2)&0x80000000)>>31)))+(!((((a/2)&0x80000000)>>31)^(((b/2)&0x80000000)>>31)))*(a*((((a/2)&0x80000000)>>31)^(!(!(a/(b|1)))))+b*(!((((a/2)&0x80000000)>>31)^(!(!(a/(b|1))))))); 
} 

int max(int a,int b) 
{ 
  return ((((a/2)&0x80000000)>>31)^(((b/2)&0x80000000)>>31))*(a*(!(((a/2)&0x80000000)>>31))+b*(!(((b/2)&0x80000000)>>31)))+(!((((a/2)&0x80000000)>>31)^(((b/2)&0x80000000)>>31)))*(a*((((a/2)&0x80000000)>>31)^(!(!(a/(b|1)))))+b*(!((((a/2)&0x80000000)>>31)^(!(!(a/(b|1)))))));
}

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved