版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、按位與 按位或 按位異或 運算2009-08-17 16:19:42|分類: 計算機基礎(chǔ)學習 |標簽: |字號大中小訂閱 (其實就想查一下“按位與 按位或 按位異或 運算”的意義,結(jié)果人家還附送了好多資料,我也就老實不客氣的照搬過來了)摘自:/question/32807257.html1. 按位與運算 按位與運算符&是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相與。只有對應的兩個二進位均為1時,結(jié)果位才為1 ,否則為0。參與運算的數(shù)以補碼方式出現(xiàn)。 例如:9&5可寫算式如下: 00001001 (9的二進制補碼)&00000101 (5的二進
2、制補碼) 00000001 (1的二進制補碼)可見9&5=1。 按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進制數(shù)為0000000011111111)。 應用: a. 清零特定位 (mask中特定位置0,其它位為1,s=s&mask) b. 取某數(shù)中指定位 (mask中特定位置1,其它位為0,s=s&mask) 2. 按位或運算 按位或運算符“|”是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相或。只要對應的二個二進位有一個為1時,結(jié)果位就為1。參與運算的兩個數(shù)均以補碼出現(xiàn)。 例如:9|5可寫算式如下: 0
3、0001001|00000101 00001101 (十進制為13)可見9|5=13 應用: 常用來將源操作數(shù)某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s|mask) 3. 按位異或運算 按位異或運算符“”是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相異或,當兩對應的二進位相異時,結(jié)果為1。參與運算數(shù)仍以補碼出現(xiàn),例如95可寫成算式如下: 0000100100000101 00001100 (十進制為12) 應用: a. 使特定位的值取反 (mask中特定位置1,其它位為0 s=smask) b. 不引入第三變量,交換兩個變量的值 (設(shè) a=a1,b=b1) 目
4、標 操 作 操作后狀態(tài) a=a1b1 a=ab a=a1b1,b=b1 b=a1b1b1 b=ab a=a1b1,b=a1 a=b1a1a1 a=ab a=b1,b=a1 4. 求反運算 求反運算符為單目運算符,具有右結(jié)合性。 其功能是對參與運算的數(shù)的各二進位按位求反。例如9的運算為: (0000000000001001)結(jié)果為:1111111111110110 5. 左移運算 左移運算符“”是雙目運算符。其功能把“ ”左邊的運算數(shù)的各二進位全部左移若干位,由“”右邊的數(shù)指定移動的位數(shù), 高位丟棄,低位補0。 其值相當于乘2。例如: a”是雙目運算符。其功能是把“ ”左邊的運算數(shù)的各二進位全部
5、右移若干位,“”右邊的數(shù)指定移動的位數(shù)。其值相當于除2。 例如:設(shè) a=15,a2 表示把000001111右移為00000011(十進制3)。對于左邊移出的空位,如果是正數(shù)則空位補0,若為負數(shù),可能補0或補1,這取決于所用的計算機系統(tǒng)。移入0的叫邏輯右移,移入1的叫算術(shù)右移,Turbo C采用邏輯右移。 main() unsigned a,b; printf(input a number: ); scanf(%d,&a); b=a5; b=b&15; printf(a=%d b=%d ,a,b); 再看一例: main() char a=a,b=b; int p,c,d; p=a; p=(p
6、8; printf(a=%d b=%d c=%d d=%d ,a,b,c,d); 浮點數(shù)的存儲格式: 浮點數(shù)的存儲格式是符號+階碼(定點整數(shù))+尾數(shù)(定點小數(shù)) SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM 即1位符號位(0為正,1為負),8位指數(shù)位,23位尾數(shù)位 浮點數(shù)存儲前先轉(zhuǎn)化成2的k次方形式,即: f = A1*2k + A2*2(k-1) + . + Ak +. +An*2(-m) (Ai = 0, 1, A1 = 1) 如5.5=22 + 20 + 2(-1) 其中的k就是指數(shù),加127后組成8位指數(shù)位 5.5的指數(shù)位就是2+127 = 129 = 100000
7、01 A2A3.An就是尾數(shù)位,不足23位后補0 所以5.5 = 01000000101000000000000000000000 = 40A00000 所以,對浮點數(shù)*2、/2只要對8位符號位+、- 即可,但不是左移、右移 關(guān)于unsigned int 和 int 的在位運算上的不同,下面有個CU上的例子描述的很清楚: 問題:這個函數(shù)有什么問題嗎? /* * 本函數(shù)將兩個16比特位的值連結(jié)成為一個32比特位的值。 * 參數(shù):sHighBits 高16位 * sLowBits 低16位 * 返回:32位值 */ long CatenateBits16(short sHighBits, shor
8、t sLowBits) long lResult = 0; /* 32位值的臨時變量*/ /* 將第一個16位值放入32位值的高16位 */ lResult = sHighBits; lResult = 16; /* 清除32位值的低16位 */ lResult &= 0xFFFF0000; /* 將第二個16位值放入32位值的低16位 */ lResult |= (long)sLowBits; return lResult; / 問題的發(fā)現(xiàn): 我們先看如下測試代碼: / int main() short sHighBits1 = 0x7fff; short sHighBits2 = 0x8f
9、12; unsigned short usHighBits3 = 0xff12; short sLowBits1 = 0x7bcd; long lResult = 0; printf(sHighBits1 + sLowBits1 ; lResult = CatenateBits16(sHighBits1, sLowBits1); printf(lResult = %08x , lResult, lResult); lResult = CatenateBits16(sHighBits2, sLowBits1); printf(lResult = %08x , lResult, lResult);
10、 lResult = CatenateBits16(usHighBits3, sLowBits1); printf(lResult = %08x , lResult, lResult); / 運行結(jié)果為: sHighBits1 + sLowBits1 lResult = 7fff7bcd lResult = 8f127bcd lResult = ff127bcd 嗯,運行很正確嘛于是我們就放心的在自己的程序中使用起這個函數(shù)來了。 可是忽然有一天,我們的一個程序無論如何結(jié)果都不對!經(jīng)過n個小時的檢查和調(diào)試,最后終于追蹤到CatenateBits16() !?它的返回值居然是錯的! “郁悶!”你說
11、,“這個函數(shù)怎么會有問題呢???” 可是,更郁悶的還在后頭呢,因為你把程序中的輸入量作為參數(shù),在一個簡單的main()里面單步調(diào)試: / int main() short sHighBits1 = 0x7FFF; short sHighBits2 = 0x8F12; unsigned short usHighBits3 = 0x8F12; short sLowBits1 = 0x7BCD; /你實際使用的參數(shù) short sLowBits2 = 0x8BCD; /你實際使用的參數(shù) long lResult = 0; printf(sHighBits1 + sLowBits1 ; lResult
12、= CatenateBits16(sHighBits1, sLowBits1); printf(lResult = %08x , lResult, lResult); lResult = CatenateBits16(sHighBits2, sLowBits1); printf(lResult = %08x , lResult, lResult); lResult = CatenateBits16(usHighBits3, sLowBits1); printf(lResult = %08x , lResult, lResult); printf( sHighBits1 + sLowBits2
13、; lResult = CatenateBits16(sHighBits1, sLowBits2); printf(lResult = %08x , lResult, lResult); lResult = CatenateBits16(sHighBits2, sLowBits2); printf(lResult = %08x , lResult, lResult); lResult = CatenateBits16(usHighBits3, sLowBits2); printf(lResult = %08x , lResult, lResult); return 0; / 發(fā)現(xiàn)結(jié)果竟然是:
14、sHighBits1 + sLowBits1 lResult = 7fff7bcd lResult = 8f127bcd lResult = 8f127bcd sHighBits1 + sLowBits2 lResult = ffff8bcd /oops! lResult = ffff8bcd /oops! lResult = ffff8bcd /oops! 前一次還好好的,后一次就ffff了?X檔案? X檔案的真相: 注意那兩個我們用來當作低16位值的sLowBits1和sLowBits2。 已知: 使用 sLowBits1 = 0x7bcd 時,函數(shù)返回正確的值; 使用 sLowBits2
15、 = 0x8bcd 時,函數(shù)中發(fā)生X檔案。 那么,sLowBits1與sLowBits2有什么區(qū)別? 注意了,sLowBits1和sLowBits2都是short型(而不是unsigned short),所以在這里,sLowBits1代表一個正數(shù)值,而sLowBits2卻代表了一個負數(shù)值(因為8即是二進制1000,sLowBits2最高位是1)。 再看CatenateBits16()函數(shù): / long CatenateBits16(short sHighBits, short sLowBits) long lResult = 0; /* 32位值的臨時變量*/ /* 將第一個16位值放入32
16、位值的高16位 */ lResult = sHighBits; lResult = 16; /* 清除32位值的低16位 */ lResult &= 0xFFFF0000; /* 將第二個16位值放入32位值的低16位 */ lResult |= (long)sLowBits; /注意這一句! return lResult; / 如果我們在函數(shù)中用 printf(sLowBits = %04x , sLowBits); 打印傳入的sLowBits值,會發(fā)現(xiàn) sLowBits = 0x7bcd 時,打印結(jié)果為 sLowBits = 7bcd 而sLowBits = 0x8bcd時,打印結(jié)果為 s
17、LowBits = ffff8bcd 是的,即使用%04x也打印出8位十六進制。 因此,我們看出來了: 當sLowBits = 0x8bcd時,函數(shù)中 lResult |= (long)sLowBits; 這一句執(zhí)行,會先將sLowBits轉(zhuǎn)換為 0xffff8bcd 再與lResult做或運算。由于現(xiàn)在lResult的值為 0xXXXX0000 (其中XXXX是任何值),所以顯然,無論sHighBits是什么值,最后結(jié)果都會是 0xffff8bcd 而當sLowBits = 0x7bcd時,函數(shù)中 lResult |= (long)sLowBits; 這一句執(zhí)行,會先將sLowBits轉(zhuǎn)換為
18、 0x00007bcd 再與lResult做或運算。這樣做或運算出來的結(jié)果當然就是對的。 也就是說,CatenateBits16()在sLowBits的最高位為0的時候表現(xiàn)正常,而在最高位為1的時候出現(xiàn)偏差。 教訓:在某些情況下作位運算和位處理的時候,考慮使用無符號數(shù)值因為這個時候往往不需要處理符號。即使你需要的有符號的數(shù)值,那么也應該考慮自行在調(diào)用CatenateBits16()前后做轉(zhuǎn)換畢竟在位處理中,有符號數(shù)值相當詭異! 下面這個CatenateBits16()版本應該會好一些: / unsigned long CatenateBits16(unsigned short sHighBits, unsigned short sLowBits) long lResult = 0; /* 將第一個16位值放入
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中職植物保護(農(nóng)藥應用)試題及答案
- 2025年高職數(shù)字媒體(VR制作進階)試題及答案
- 2025年大學歷史(世界近現(xiàn)代史)試題及答案
- 2025年大學化工類(化工安全規(guī)范)試題及答案
- 大學(藥學)藥物分析技術(shù)2026年綜合測試題及答案
- 2025年大學大四(交通運輸)交通運輸綜合試題及答案
- 2025年大學攝影(攝影教育心理學)試題及答案
- 2025年中職地質(zhì)工程技術(shù)(地質(zhì)勘探基礎(chǔ))試題及答案
- 2025年大學大三(會展經(jīng)濟與管理)會展經(jīng)濟分析階段測試題及答案
- 2025年大學大三(生物科學)細胞生物學實驗階段測試題及答案
- 中國工藝美術(shù)館招聘筆試試卷2021
- 申論范文寶典
- 【一例擴張型心肌病合并心力衰竭患者的個案護理】5400字【論文】
- 四川橋梁工程系梁專項施工方案
- DB32T 3695-2019房屋面積測算技術(shù)規(guī)程
- 貴州省納雍縣水東鄉(xiāng)水東鉬鎳礦采礦權(quán)評估報告
- GB 8270-2014食品安全國家標準食品添加劑甜菊糖苷
- 2023年杭州臨平環(huán)境科技有限公司招聘筆試題庫及答案解析
- 易制毒化學品日常管理有關(guān)問題權(quán)威解釋和答疑
- 湖北省高等教育自學考試
- 企業(yè)三級安全生產(chǎn)標準化評定表(新版)
評論
0/150
提交評論