位運算
- 定義
-
- 位運算的用途
- 位運算符
- 如何使用位運算符
-
- AND(&)運算符的用法
- OR(|)運算符的使用方法
- 如何使用XOR(^)運算符
- NOT(~)運算符的使用方法(位反轉)
- 移位運算
-
- 左移(<<)運算符
- 右移(>>)運算符
- 負值的移位運算
- 結束語
定義
位運算是以二進制數的0或1表示的位為機關計算的。
在FLG的确認中經常使用,也是了解PC的結構不可缺少的項目。
在C語言中,通過使用後面說明的位運算符,可以簡單地進行計算,是以要了解結構。
位運算的用途
PC以二進制數計算是一個簡單的計算公式,是以處理速度往往會非常快。
在處理數百萬到成千上萬像素的圖像時,通常會通過位運算來計算耗時的處理。
另外,由于記憶體使用量也有少的傾向,是以像微型計算機一樣使用記憶體少的硬體的情況下,也經常用位運算來計算。
位運算符
位運算符是用于計算位的運算符。
就像我們在計算的時候想到的加法的“+”之類的東西。
位運算符的類型
位運算符 | 說明 |
---|---|
& | right-aligned AND。當兩者都為1時,将其設定為1,否則将其設定為0的運算符 |
| | OR。隻有當兩者都為0時才為0。否則将其設定為1的運算符 |
^ | XOR。當兩者都是不同的值時1。其他為0的運算符 |
~ | NOT。0是1,1是将其反轉為0的運算符 |
>> | 通過移位運算向右偏移。它類似于十進制數所說的位移動,移動所有位的位。運算方法根據考慮或不考慮符号而不同 |
<< | 通過移位運算向左偏移 |
如何使用位運算符
在這裡,因為C語言的編譯器使用GCC,是以像“0b1010”一樣,在數值的開頭加上“0b”處理2進制數。
請注意,根據環境的不同,即使加上“0b”也不能作為二進制數來處理。
AND(&)運算符的用法
&運算符被标記為A&B,A和B都是1時為1,其他為0的運算符。
用程式看那個情況确認一下吧。
注意,我們通常使用printf函數來顯示執行結果,但是printf函數不能顯示二進制數。
是以,我們建立了一個二進制顯示函數,并顯示了計算結果。
#include <stdio.h>
// 二進制數表示的函數
void printBi(int num) {
int len = 4;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
int num1, num2, result;
num1 = 0b0101;
num2 = 0b0011;
result = num1 & num2;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
上述的程式,把num1和num2 AND運算的結果變量代入result。
通過比較num1和num2的相同位數的位,您可以從程式中确認隻有當兩者為1時才為1。
另外,簡單說明二進制數表示用的函數printBi。
我們正在使用變量x檢查哪個位數的值是1。
首先,在表達式“1<<i”中,數字按順序移位。
運算符“<<”稱為左移運算符,稍後将在位移運算中詳細說明。
接下來,如果要使用AND運算符“&”檢查的位數為1,則傳回1,否則傳回0。
使用右移運算符“>>”将傳回的值移位到第一位,并将結果存儲在數組位元素中。
然後,由于每個數字的值被存儲在數組位的每個元素中,是以它一個接一個地顯示。
OR(|)運算符的使用方法
|運算符被标記為A|B,它是一個運算符,如果A和B都是0,則傳回0,否則是1。用程式看那個情況确認一下吧。
#include <stdio.h>
// 二進制數表示的函數
void printBi(int num) {
int len = 4;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
int num1, num2, result;
num1 = 0b0101;
num2 = 0b0011;
result = num1 | num2;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
上述的程式,num1和num2 OR運算的結果變量result代入。
通過比較num1和num2的相同位數的位,您可以從程式中确認,如果兩者都為0,則為0,否則為1。
如何使用XOR(^)運算符
運算符标記為A^B,在A和B不同的情況下傳回1,A和B在相同的情況下傳回0。
用程式看那個情況确認一下吧。
#include <stdio.h>
// 二進制數表示的函數
void printBi(int num) {
int len = 4;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
int num1, num2, result;
num1 = 0b0101;
num2 = 0b0011;
result = num1 ^ num2;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
上述的程式,num1和num2 XOR運算,其結果變量result代入。
通過比較num1和num2的相同位數的位,您可以從程式中确認隻有當兩者不同時才為1。
NOT(~)運算符的使用方法(位反轉)
運算符是表示為~A,A為1時為0,A為0時為1的運算符。
這被稱為位反轉。
在位反轉的情況下,也需要考慮負值,是以我們使用char類型以8位簡單易懂的方式進行解釋。
int類型取決于16位或32位,因為計算結果會發生變化。
讓我們在實際程式中确認一下。
#include <stdio.h>
// 二進制數表示的函數
void printBi(char num) {
int len = 8;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
int num;
int result;
// 将0反轉為1
num = 0b00000000;
result = ~num;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
// 将1反轉為0
num = 0b00001111;
result = ~num;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
二進制數:0b11111111(十進制數:-1)
二進制數:0b11110000(十進制數:-16)
上述的程式,2進制數0和2進制數1111反轉表示。
可以确認,0是1,1是0,0是0。
順便說一下,在帶符号的二進制數中,最左筷子表示符号。
這叫做補數。0表示正數,1表示負數。
是以,如果在十進制數中以二進制數反轉正數,則在十進制數中為負值。負值的二進制數字是通過反轉所有位并添加1來建立的。
移位運算
作為應用的使用方法,解說移位運算的使用方法。
移位運算是位的位移動。
int型的話16bit還是32bit根據環境的不同而變化,是以使用char型簡單易懂地用8bit進行解說。
因為以二進制數為基準來考慮,是以向左移動的話值就會翻倍,向右移動的話值就會變成1/2。
另外,需要注意的是,如果移位操作中的數字溢出,則不會成為正确的值。
左移(<<)運算符
左移運算符(<<)标記為A<<1,是将以二進制數表示的A向左移動一位數的運算符。
左移時,左側溢出的位将被删除,右側将添加0。
讓我們在實際程式中檢查左移運算。
#include <stdio.h>
// 二進制數表示的函數
void printBi(char num) {
int len = 8;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
char num, result;
// 十進制數的14用二進制數表示
num = 0b00001110;
printf("%dn", num);
// 将num向左移位1位
result = num << 1;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
14
二進制數:0b00011100(十進制數:28)
上述的程式num 2進制“0000 1110”進入,num 1位左移的結果變量result代入表示。
如果将該二進制數向左移位一位數,則為“0001 1100”,因為向左偏移位數。在右端添加了0。
如果将其修改為十進制數,則是原始值“14”乘以兩倍的值“28”。
右移(>>)運算符
右移運算符(>>)标記為A>>1,是将以二進制數表示的A向右移動一位數的運算符。右移時,右側溢出的位将被删除,左側将添加0。
讓我們在實際程式中檢查右移運算。
#include <stdio.h>
// 二進制數表示的函數
void printBi(char num) {
int len = 8;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
char num, result;
// 十進制數的14用二進制數表示
num = 0b00001110;
printf("%dn", num);
// 将num向右移位1位
result = num >> 1;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
14
二進制數:0b00000111(十進制數:7)
上述的程式num 2進制“0000 1110”進入,num 1位右移的結果變量result代入表示。右移将數字移動到右邊。
将“0000 1110”向右移位一位數,是以為“0000 0111”。
右邊的數字将被删除,左邊的數字将被添加到0。
如果将其修改為十進制數,則将原始值“14”設定為1/2的值的“7”。
負值的移位運算
移位運算包括邏輯移位和算術移位。
邏輯移位簡單地移位所有的位。
在算術移位的情況下,移位最高有效位以外的位,以便符号不變。
請注意,在負數移位運算中,隻有在右移的情況下,移位的部分左側才會添加1。
讓我們來看看實際的程式。
#include <stdio.h>
// 二進制數表示的函數
void printBi(char num) {
int len = 8;
int bit[8];
int x;
for(int i = 0; i < len; i++) {
x = 1 << i;
x = num & x;
bit[len - i - 1] = x >> i;
}
printf("0b");
for(int i = 0; i < len; i++) {
printf("%d", bit[i]);
}
}
int main(void) {
char num, result;
// 負值-14右移時
num = 0b11110010;
printf("%dn", num);
result = num >> 1;
// 用二進制數和十進制數表示運算結果
printf("二進制數:");
printBi(result);
printf("(十進制數:%d)n", result);
return 0;
}
執行結果:
-14
二進制數:0b11111001(十進制數:-7)
在上述程式中,變量num包含“1111 0010”。
在負值的情況下,左端是表示符号的位,是以即使向右移動符号也不會改變,左端進入1。是以,成為“1111 1001”。
如果将其修改為十進制數,則将原始值“-14”設定為1/2的值的“-7”。
結束語
位運算包括AND運算符、OR運算符、XOR運算符、NOT運算符、右移運算符和左移運算符。