C/C++/JAVA 二進位/十六進位 的應用 :大數(超過32位位元),按位邏輯運算,屬性值設定,等

來源:互聯網
上載者:User
按位邏輯運算,屬性設定

按位邏輯運算在高效率的資料操作中應用很多,平時用的進階語言裡面,多數時候不需要我們去手動設定這些,因為已經被封裝在各種模組/類裡面了。

在需要手動定義一些功能的時候,這些運算方法很值得使用。
有一點要注意就是,所有按位元運算都是二進位位的按位元運算,如果資料採用十進位或者十六進位表示,實際上也是採用二進位的按位元運算。 按位與: &

 0&0=0; 1&0=0; 0&1=0; 1&1=1;

(1不變,0變為0)
例如 : 1001&0011 = 0001
負數在電腦中是按照補碼的形式儲存的,所以要按照補碼來按位元運算
應用:
1,把指定位清零 。只需要和指定位為0,其他位為1的數進行&運算,這些位就為被置0
2,擷取指定位。構造一個位元,需要擷取的位為1,其他位為0,按位&運算,其結果就是資料的指定位。 按位或: |

0|0=0;   0|1=1;   1|0=1;    1|1=1;

(0不變,1變為1)
應用:
1,把資料的指定位設定為1。例如,如果要把第四位設定為1,那麼需要構造一個位元:1000,將其與資料進行|預算,那麼資料的第四位就會設定為1(不論之前是否是1) 按位異或:^

0^0=0;   0^1=1;   1^0=1;   1^1=0;

(0不變,1反轉)
應用:
1,與1異或,可以翻轉
2,與0異或,可以保留原值。
這兩點很明確。 按位取反:~

~1=0;   ~0=1;
一個按位邏輯運算的應用:屬性設定(這個應該有一個學名,暫時還不知道怎麼說)

要對一個項目設定一些屬性。如果是唯一性的屬性倒還好辦,比如說,一個項目,可能的屬性為a,b,c,只能是其中一種,那麼只需要設定這些屬性值為一個靜態常量,然後去判斷一下就好了。

但是很多時候需要設定的屬性是多種疊加的。比如說,可能屬性是,a,b,c,d,e,f,g。
可以是其中一種,或者幾種,可以是ac,也可以是dfg,也可以是e。並且這些屬性並沒有明確的分類,大多數都是同一類屬性的疊加,所以不能分到不同的屬性值裡面去。
具體來講,一個視窗,可以是 前台/最大化/透明/視窗化/預設位置/保持最上層 等等這些屬性的一個或者幾個的疊加。一個檔案可以是 檔案/檔案夾/系統檔案/隱藏檔案/使用者檔案 等等這些的一個或者幾個的疊加。

這個時候,像唯一屬性那樣判斷就不好用了。最好的辦法就是用按位邏輯運算

假設一個項目的屬性有8種。那麼就構造一個8位位元(也就是2位十六進位數)。每一位對應一個屬性,設定成靜態常量。
a: 0000 0001
b: 0000 0010
c: 0000 0100
d: 0000 1000
…………
如此一來,就可以用按位邏輯運算來構造屬性值了。
比如說,我的屬性值是abc,那麼構造出的值就是:a|b|c.
根據之前的描述,| 運算將會使得對應1的位置是1,也就是說,a|b|c = 0000 0111,這也是一個唯一值,跟所有8種可能屬性都不重複。類似的,我們也可以構造出其他的疊加屬性,0100 1101,1001 0000 等等

判斷屬性的時候,需要用到 & 運算。
例如,判斷一個項目是否有 a屬性,可以:if((attr&a)==a)
根據上面的描述,& 的功能是 :0變為0,1不變。也就是說, attr的值,對應a裡面的為0的位,不管是否是0,都會編程0;對應a裡面為1的位,則保持不變。
所以,如果attr有a這個屬性,那麼它的對應a屬性的位就會是1,就保持為1;如果沒有a這個屬性,對應為就是0,運算後依然是0。
而其他位,不管是否是0,都會變成0.因此,可以用if((attr&a)==a)來判斷屬性。

同理,設定屬性的時候用到 | 運算。
假設attr要設定成abcd,只需要簡單的這樣: attr = a|b|c|d;就可以了 大數(超過32位位元)

C語言早已支援64位,有單獨的方法操作64位元(目前為止還沒有實驗過),但是多數時候我們還是在32位裡面運算。

在沒有支援64位元的時期,要儲存一個大資料,比如檔案大小,需要用到高低位的儲存方法。就是說,在屬性裡面會對應兩個值,一個是低32位,一個是高32位。

在資料量比較小的時候,高位始終為0。如果資料量在低位溢出,就會在高位中 +1。
需要注意一點就是,如果直接寫出來的話,只有二進位/十六進位可以直接表示為 【高位-低位】,例如一個數是低位0x1820 ff11, 高位是0x1,那表示出來就是 0x1 1820 ff11
如果是十進位,就需要轉換一下,因為高位的 0x1 表示成十進位的時候是 32位最大值+1

如果要做加法,需要高位/低位分開相加,如果低位產生了進位,那就在高位的結果裡面加1.
怎麼判斷低位的進位呢。
如果是無符號數,就簡單了,因為進位以後的32位值對應的就只有這32位的值,第33位會被電腦直接忽略,所以,如果 結果小於任意一個相加值,就表示產生了進位。
numA + numB = result;
if(result<numA)…………
有符號數的情況還沒有研究過。剛才這個方法也是在網上找到的,還沒細看是否有bug。 高低位的表示方法轉換成10進位

result = HIGH*(MAXDWORD + 1) + LOW
result – 真實結果
MAXDWORD – 32位元最大值 (0xFFFF FFFF)

那麼,怎麼表示在電腦裡面呢。
0xFFFF FFFF 十進位 就是 4 294 967 295,0x1 0000 0000 實際數值是 4 294 967 296,但是電腦裡面直接把超過32位的數值捨去,所以電腦裡面這個數就是0x0000 0000,也就是十進位數0

要在電腦上表示超過32位的數值,可以使用以下辦法。(自己想的辦法,不知道是不是實用)

儲存一個指定位元(例如,20位十進位數)的字元數組char bit[20];
將這個數組的每一個位上的字元,對應十進位數的每一個位的數字,然後按照普通的演算法進行加減乘除操作。
加法就是 對位相加,如果進位,就在上一位加1。
乘法類似。
除法還沒有仔細想過,以後再說吧。

所以,超過32位的數值可以用這種按位標記法來儲存,輸出的時候也不會存在溢出的問題。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.