紀念一下
不准在函數體中使用任何比較運算,比如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))))))); }