C++位運算常見操作
一些位運算的常見操作整理如下注意位運算操作符的優先級都非常低盡量記得加括號。給第n位(從右邊開始數初始位置0)值置1int set_bit(int x, int n){ return x | (1 n); }清除第n位(從右邊開始數初始位置0)int clear_bit(int x, int n){ return x ~ (1 n); }得到第n位(從右邊開始數初始位置0)bool get_bit(int x, int n){ return x (1 n); }注意int數字的第n位和string數字的第n位不一樣int數字 (例如 011100110110001) 的第n位是從右往左數string數字 (例如011100110110001)的第n位通常是從左往右數。a ^ b (異或)是不進位加法即 a ^ b 相加之后該進位的地方不進位的結果。 a b 就是a 和 b 里都是1的那些位置。一個例子如下:不用完成加法的算法int aplusb(int a, int b) { while (b) { int a1 a ^ b; int b1 (a b) 1; a a1; b b1; } return a; }以a3 (0011) b5(0101)為例。a 0011 0110 0100 0000 1000 (return) //未進位加法和b 0101 0010 0100 1000 0000 //進位遞歸版本如下int aplusb(int a, int b) { if (a 0) return b; if (b 0) return a; return aplusb((a b) 1, a ^ b); }消去二進制中最右側的那個1:x (x - 1)一些例子如下檢查n是否為2的冪次位bool checkPowerOf2(int n) { return n 0 (n (n - 1)) 0; }計算一個32位整數有多少個1int countOnes(int num) { int count 0; while (num) { count; num num - 1; } return count; }計算a要反轉多少位變成bint bitSwapRequired(int a, int b) { int c a ^ b; int count 0; while (c) { count; c c - 1; } return count; }x (-x) 是x的最右邊一個1的位置對應的數 (注意x(x-1)是將其該位消去)。如12 (-12) 返回4。8 (-8) 返回8。這個技巧是線段樹(Binary Index Tree)算法里面的核心技巧(見Lowbit(x))。取反操作~正整數的按位取反是其本身1的負數A (1)10 (00000000000000000000000000000001)2~A ~ (1)10 (11111111111111111111111111111110)2 (-2)10負整數的按位取反是其本身1的絕對值零的按位取反是 -1基于union的bitmap的操作。typedef union { int all; struct { int flag0 : 1; //bit 0 int flag1 : 1; //bit 1 int flag2 : 1; //bit 2 ... int flag15 : 1; //bit 15 int rsvd : 16; //bit 16-31 } bits; }cntl_t; #define BIT(x) 1((n)) cntl_t cntl;對flag2的操作如下#define clear_flag2() (cntl.bits.all ~BIT(2)) #define set_flag2() (cntl.bits.all | BIT(2)) #define get_flag2() (cntl.bits.flag2)也可以直接對flag進行讀寫操作。比如說cntl.bibts.flag2 3;下面這個鏈接對C/C bit field的操作說的非常清楚是一個非常好的鏈接。https://aticleworld.com/bit-field-in-c/Gray Code 的生成一種方法是基于i ^ (i 1)。負數的移位很重要C/C中左移是邏輯移位右端補0所以負數左移有可能變成正數C/C中右移是算數移位左端補齊最高位的符號位。負數右移肯定還是負數。引用https://blog.csdn.net/e3399/article/details/7526230的例子/********************************************************************** * Compiler: GCC ************************************************************************/ #include stdio.h int main(int argc, char **argv) { int i 0x8000000f; //這里的0x8000000f為int型數據的補碼形式 int j i 3; //右移是算術移位左端補齊的是符號位 int k i 1; //左移是邏輯移位右端補0 printf(%d %x\n, i, i); printf(%d %x\n, j, j); printf(%d %x\n, k, k); i -9; printf(%d %x\n, i, i); i 0xfffffff7; j i 3; k i 1; printf(%d %x\n, i, i); printf(%d %x\n, j, j); printf(%d %x\n, k, k); return 0; }Output:-2147483633 8000000f-268435455 f000000130 1e-9 fffffff7-9 fffffff7-2 fffffffe-18 ffffffee注意-9 1 -18, 并不是乘2這么簡單。-9的補碼是0xffffffff71后變成0xffffffEE即1111…1110 1110此即-18的補碼。用16進制的形式對數據進行賦值這16進制的數代表的是補碼補碼負數的補碼是在其原碼的基礎上,符號位不變, 其余各位取反, 最后1. (即在反碼的基礎上1)[1] [00000001]原 [00000001]反 [00000001]補[-1] [10000001]原 [11111110]反 [11111111]補i 0xfffffff7; //0xfffffff7是補碼而不是原碼故i -9 printf(%d %x\n, i, i); i -9; printf(%d %x\n, i, i); //故兩個printf輸出結果相同12取模運算可以用a % b a - (a / b) * b如果b為2的n次方可用a % b a (b - 1)2147483648實際上是存的-2147483648?因為2147483647 01111111 11111111 11111111 11111111-2147483647表示為(2的補碼)10000000 00000000 00000000 00000001-2147483648(2的補碼)還可以比-2147483647少1所以是10000000 00000000 00000000 00000000另外實際上補碼的補碼就是原碼(數的原始表示)所以10000000 00000000 00000000 00000000 的補碼是11111111 11111111 11111111 11111111 1第一個1是負號所以1111111 11111111 11111111 11111111 1 10000000 00000000 00000000 000000002147483648這里第一個1是實際數字。加上負號即-2147483648。另外11111111,11111111,11111111,11111111看起來很大實際上是存的-1。位運算如果和硬件結合起來會更快。比如說ARM芯片支持__clz()內置函數返回某無符號整數的前置0的個數。Syntax: unsigned char __clz(unsigned int val) Return value The __clz intrinsic returns the number of leading zeros in val.有了__clz()函數我們就可以定義下面的MSB(x)宏來返回MSB比特(即從高到低第一個1)的位置。#define MSB(x) (31- __clz((unsigned int)x))注意這里默認一個unsigned int占4個字節。用下面的循環我們可以快速遍歷一個unsigned int (即下面的bitmap)的1注意while里面的操作次數就是bitmap里面的1比特的個數。unsigned int bitmap 0x1234; while (bitmap) { int pos MSB(bitmap); //do something bitmap ~(0x1 pos); }如果n是2^k那么x % n x (n - 1)顯然后者更快。比如說33 % 8 33 7 1, 37 % 8 37 7 5Round up to the next highest power of 2from https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2unsignedintv;// compute the next highest power of 2 of 32-bit vv--;v|v1;v|v2;v|v4;v|v8;v|v16;v;從一個整數中提取 [start, start width) bit field意思是從 bit start 開始一共提取 width 個 bitsbit 編號從最低位 0 開始核心公式field (value start) mask;其中mask (1U width) - 1U;Example:value 1101 0110提取[start, start width) [2, 6)也就是 bit [5:2]value 11 0101 10↑↑↑↑bits 5:2 0101代碼uint32_t value 0xD6U; /* 1101 0110 */unsigned start 2;unsigned width 4;uint32_t mask (1U width) - 1U;uint32_t field (value start) mask;value 2 0b1101 0110 2 0b0011 0101mask 0b00001111field (value start) mask 0b0101 5

相關新聞

AI 電動竹火炬智能功率 MOSFET 完整選型方案

AI 電動竹火炬智能功率 MOSFET 完整選型方案

AI 電動竹火炬集成了智能照明、動態色彩控制與電池管理,對功率 MOSFET 提出了高集成度、低功耗、高響應速度的要求。微碧半導體(VBsemi)基于先進的 Trench 工藝,為您提供覆蓋電機驅動、燈光控制、電源管理的完整 AI 竹火炬功率解決…

2026/8/2 5:53:54 閱讀更多
Python熱力圖繪制全攻略:從Matplotlib到Plotly的實戰技巧

Python熱力圖繪制全攻略:從Matplotlib到Plotly的實戰技巧

1. 項目概述:為什么熱力圖是數據可視化的“瑞士軍刀”? 如果你經常和數據打交道,無論是分析用戶行為、監控系統指標,還是研究地理分布,總會遇到一堆密密麻麻的數字表格。盯著這些數字看久了,不僅眼睛累&…

2026/8/2 16:26:28 閱讀更多
MountainCar 認知控制器

MountainCar 認知控制器

文章目錄MountainCar 認知控制器 對外白皮書一個讓小車學會“后退才能前進”的AI一、為什么是MountainCar?1.1 一個看似簡單實則棘手的問題1.2 為什么它很難?二、我們的方法2.1 核心理念:找到專家,然后復制他2.2 為什么這種方法有…

2026/8/2 16:26:28 閱讀更多
單片機畢設項目:多路病患無線呼叫信號優先級排序硬件系統實現 基于 51/STM32 的病床呼叫發射與醫護接收終端設計(020201)

單片機畢設項目:多路病患無線呼叫信號優先級排序硬件系統實現 基于 51/STM32 的病床呼叫發射與醫護接收終端設計(020201)

博主介紹:??碼農一枚 ,專注于大學生項目實戰開發、講解和畢業🚢文撰寫修改等。全棧領域優質創作者,博客之星、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于嵌入式單片機,Java、小程序技術領域和畢業項目實戰 ??…

2026/8/2 16:16:28 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費下載鏈接】GetQzonehistory 獲取QQ空間發布的歷史說說 項目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費下載鏈接】GetQzonehistory 獲取QQ空間發布的歷史說說 項目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應用材料(Applied Materials)公司生產的一款用于半導體設備的I/O信號分配電路板。該型號(0100-02186)的核心特點如下:專用于Endura等半導體工藝腔室。集成信號路由與分配功能。連接控制…

2026/8/2 2:51:21 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機是日本日清(Nissei)品牌的一款工業用三相異步電機,適用于自動化設備及通用機械驅動。該型號(FFMN-32L-10-T0 40AX)的核心特點如下:三相交流異步電動機。額定…

2026/8/2 2:52:49 閱讀更多