摘要:總結對于原二進制數來說,是不變,是反轉。的位數對應原二進制數的位數,對各位進行屏蔽,全部置。左移左移與右移比較類似,是將目標二進制數字向左右移動相應的位數。語言中的邏輯運算符按位與,按位或,按位異或,取反,左右移位不完全手冊立創開源
運算符 | 含義 |
---|---|
& | 按位與 |
| | 按位或 |
^ | 按位異或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
c 語言中存在以上 6 個位操作運算符,且它們只能用于整形操作數。
總結:對于原二進制數來說,&0
是屏蔽,&1
是不變。
總結:對于原二進制數來說,|0
是不變,|1
是置1。
總結:對于原二進制數來說,^0
是不變,^1
是反轉。
按位與的定義是:同一二進制位上的數字都是1的話,& 的結果為1,否則為0。
運算 | 結果 |
---|---|
0 & 0 | 0 |
0 & 1 | 0 |
1 & 0 | 0 |
1 & 1 | 1 |
根據這個特性,& 操作常常用來屏蔽特定的二進制位。
例如:0000 1111 & 0000 0011 = 0000 0011
與運算 | 0 0 0 0 1 1 1 1 |
& | 0 0 0 0 0 0 1 1 |
結果 | 0 0 0 0 0 0 1 1 |
可以看見,1111的前兩位被屏蔽成為0了。
所以如果想清空數據,只需要將原二進制數與上 &0 就可以了。0的位數對應原二進制數的位數,對各位進行屏蔽,全部置0。
相對的,&可以利用0來屏蔽,也可以用1來讀取。
例如: 一個二進制數 1101 1001,我只想要它的后四位,怎么辦呢?
只需要進行如下操作:1101 1001 & 0000 1111即可。
與運算 | 1 1 0 1 1 0 0 1 |
& | 0 0 0 0 1 1 1 1 |
結果 | 0 0 0 0 1 0 0 1 |
其實該方法是屏蔽和讀取的結合,&0保證消除無用位,&1保證有用數據的完整性。
總結:對于原二進制數來說,&0
是屏蔽,&1
是不變。
定義:只要參與運算的雙方其中有一個是1,結果就是1.同0才為0。
運算 | 結果 |
---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
主要用作將某些特定位置1。
例如:1010 0000 | 0000 1111 = 1010 1111。
或運算 | 1 0 1 0 0 0 0 0 |
| | 0 0 0 0 1 1 1 1 |
結果 | 1 0 1 0 1 1 1 1 |
總結:對于原二進制數來說,|0
是不變,|1
是置1。
只要參與運算的雙方互異,結果就為1,否則為0。
運算 | 結果 |
---|---|
0 ^ 0 | 0 |
0 ^ 1 | 1 |
1 ^ 0 | 1 |
1 ^ 1 | 0 |
可以通過上面的定義看到,一個數^1 的話就會0變成1,1變成0,而^0則不對原數進行改變。所以根據此特性可以對特定位進行0 1 反轉。
例如: 1100 1100 ^ 0000 1100 = 1100 0000。
異或運算 | 1 1 0 0 1 1 0 0 |
^ | 0 0 0 0 1 1 0 0 |
結果 | 1 1 0 0 0 0 0 0 |
同樣的,如果對一個數進行^0,代表保留原值。
總結:對于原二進制數來說,^0
是不變,^1
是反轉。
對一個二進制數進行取反。1變0,0變1。
唯一需要注意的一點是,~的優先級是邏輯運算符中最高的,必須優先計算。
左移與右移比較類似,是將目標二進制數字向左/右移動相應的位數。
左移補0:1111 1111 << 1 == 1111 1110,換算十進制的話是原來數值的2倍。
左移 | 1 1 1 1 1 1 1 1 |
<< | 1 |
結果 | 1 1 1 1 1 1 1 0 |
右移看情況:負數補1,正數補0。需要看符號位。同樣,換算為十進制數值變為原來的1/2.
右移 | 1 1 1 1 1 1 1 1 |
>> | 1 |
結果 | 0 1 1 1 1 1 1 1 |
總結:左乘右除。
比如要改變 GPIOA 的狀態,可以先對寄存器的值進行 &
清零操作
GPIOA -> CRL &= 0XFFFFFF0F; // 將第 4-7 位清 0
然后再與需要設置的值進行 |
或運算
GPIOA -> CRL |= 0X00000040; // 設置相應位的值,且不改變其他位的值
以固件庫的 GPIO 初始化的函數里一行代碼為例
GPIOx -> BSRR = (((uint32_t)0x01) << pinpos);
這個操作就是將 BSRR 寄存器的第 pinpos 位設置為 1。
為什么要通過左移而不是直接設定呢?其實,這是為了提高代碼的可讀性以及可重用性。這行代碼可以直觀明了的知道,是將第 pinpos 位設置為 1。
如果寫成
GPIOx -> BSRR = 0x0030;
這樣的代碼就不容易看出,也不好重用了。
類似的代碼還有:
GPIOA -> ORT |= 1<<5; // PA.5 輸出高,不改變其他位
這樣我們一目了然,5 告訴我們是第 5 位也就是第 6 個端口,1 告訴我們是設置成了 1。
SR 寄存器的每一位都代表一個狀態,某個時刻我們希望去設置某一位的值為 0,同時其他位都保留位 1,簡單的作法是直接給寄存器設置一個值:
TIMx -> SR = 0xFFF7;
這樣做法可讀性交較差。
看看庫函數中代碼是如何使用的:
TIMx -> SR = (uint16_t)~TIM_FLAG;
而 TIM_FLAG 是通過宏定義完成的值:
#define TIM_FLAG_Update ((uint16_t)0x0001)#define TIM_FLAG_CC1 ((uint16_t)0x0002)
看這個就容易明白,可以直接從宏定義重看出 TIM_FLAG_Update 就是設置的第 0 位了,可讀性較強。
Ref: C語言中的邏輯運算符:按位與,按位或,按位異或,取反,左右移位
Ref: STM32 不完全手冊 - 立創開源
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/120808.html
摘要:有符號的右移操作符由兩個大于符號表示這個操作符的含義就是將數值的位向右移指定的位數同時保留符號位的值正負號標記有符號的右移操作符與左移操作符剛好相反比如向右移動位就是同樣的在移位的過程中也會出 位操作符的基本概念 因為ECMAscript中所有數值都是以IEEE-75464格式存儲,所以才會誕生了位操作符的概念. 位操作符作用于最基本的層次上,因為數值按位存儲,所以位操作符的作用也就是...
摘要:原碼補碼和反碼原碼一個數在計算機中是以二進制的形式存在的,其中第一位存放符號正數為負數為。中的位運算在中按位操作符會將其操作數轉成補碼形式的有符號位整數。原文鏈接由扯到中的位運算 這個話題的由來是2016年3月份的時候 NPM 社區發生了‘left-pad’事件,不久后社區就有人發布了用來補救的,也是現在大家能用到的 left-pad 庫。 最開始這個庫的代碼是這樣的。 module....
摘要:操作符的兩個操作數必須為整數。函數調用用作為函數調用操作符。訪問一個結構的成員結構體成員名結構體指針成員名還是熟悉的栗子在之前的博客請回答語言初識語言下入門的結構體出現過的栗子名字圖鑒編號身高重量屬性類型 ...
摘要:語言基礎之操作符詳解操作符的分類算術操作符移位操作符位操作符邏輯操作符逗號表達式表達式求值隱式類型轉換算術轉換操作符的屬性今天就帶各位大佬來了解一波語言的操作符。 ...
閱讀 1370·2021-11-25 09:43
閱讀 3582·2021-11-10 11:48
閱讀 5091·2021-09-23 11:21
閱讀 1597·2019-08-30 15:55
閱讀 3508·2019-08-30 13:53
閱讀 1234·2019-08-30 10:51
閱讀 867·2019-08-29 14:20
閱讀 1971·2019-08-29 13:11