C++位運算常見操作
一些位運算的常見操作整理如下注意位運算操作符的優(yōu)先級都非常低盡量記得加括號。給第n位(從右邊開始數(shù)初始位置0)值置1int set_bit(int x, int n){ return x | (1 n); }清除第n位(從右邊開始數(shù)初始位置0)int clear_bit(int x, int n){ return x ~ (1 n); }得到第n位(從右邊開始數(shù)初始位置0)bool get_bit(int x, int n){ return x (1 n); }注意int數(shù)字的第n位和string數(shù)字的第n位不一樣int數(shù)字 (例如 011100110110001) 的第n位是從右往左數(shù)string數(shù)字 (例如011100110110001)的第n位通常是從左往右數(shù)。a ^ b (異或)是不進位加法即 a ^ b 相加之后該進位的地方不進位的結(jié)果。 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); }消去二進制中最右側(cè)的那個1:x (x - 1)一些例子如下檢查n是否為2的冪次位bool checkPowerOf2(int n) { return n 0 (n (n - 1)) 0; }計算一個32位整數(shù)有多少個1int countOnes(int num) { int count 0; while (num) { count; num num - 1; } return count; }計算a要反轉(zhuǎn)多少位變成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的位置對應的數(shù) (注意x(x-1)是將其該位消去)。如12 (-12) 返回4。8 (-8) 返回8。這個技巧是線段樹(Binary Index Tree)算法里面的核心技巧(見Lowbit(x))。取反操作~正整數(shù)的按位取反是其本身1的負數(shù)A (1)10 (00000000000000000000000000000001)2~A ~ (1)10 (11111111111111111111111111111110)2 (-2)10負整數(shù)的按位取反是其本身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)。負數(shù)的移位很重要C/C中左移是邏輯移位右端補0所以負數(shù)左移有可能變成正數(shù)C/C中右移是算數(shù)移位左端補齊最高位的符號位。負數(shù)右移肯定還是負數(shù)。引用https://blog.csdn.net/e3399/article/details/7526230的例子/********************************************************************** * Compiler: GCC ************************************************************************/ #include stdio.h int main(int argc, char **argv) { int i 0x8000000f; //這里的0x8000000f為int型數(shù)據(jù)的補碼形式 int j i 3; //右移是算術(shù)移位左端補齊的是符號位 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進制的形式對數(shù)據(jù)進行賦值這16進制的數(shù)代表的是補碼補碼負數(shù)的補碼是在其原碼的基礎上,符號位不變, 其余各位取反, 最后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輸出結(jié)果相同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另外實際上補碼的補碼就是原碼(數(shù)的原始表示)所以10000000 00000000 00000000 00000000 的補碼是11111111 11111111 11111111 11111111 1第一個1是負號所以1111111 11111111 11111111 11111111 1 10000000 00000000 00000000 000000002147483648這里第一個1是實際數(shù)字。加上負號即-2147483648。另外11111111,11111111,11111111,11111111看起來很大實際上是存的-1。位運算如果和硬件結(jié)合起來會更快。比如說ARM芯片支持__clz()內(nèi)置函數(shù)返回某無符號整數(shù)的前置0的個數(shù)。Syntax: unsigned char __clz(unsigned int val) Return value The __clz intrinsic returns the number of leading zeros in val.有了__clz()函數(shù)我們就可以定義下面的MSB(x)宏來返回MSB比特(即從高到低第一個1)的位置。#define MSB(x) (31- __clz((unsigned int)x))注意這里默認一個unsigned int占4個字節(jié)。用下面的循環(huán)我們可以快速遍歷一個unsigned int (即下面的bitmap)的1注意while里面的操作次數(shù)就是bitmap里面的1比特的個數(shù)。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;從一個整數(shù)中提取 [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

相關(guān)新聞

生成式UI革命(2024Q3實測數(shù)據(jù)曝光):Figma+AI插件已讓原型交付效率提升680%

生成式UI革命(2024Q3實測數(shù)據(jù)曝光):Figma+AI插件已讓原型交付效率提升680%

更多請點擊: https://codechina.net 第一章:生成式UI革命的定義與核心范式躍遷 生成式UI革命并非簡單地將大語言模型嵌入界面,而是重構(gòu)人機交互的根本契約:從“用戶驅(qū)動指令”轉(zhuǎn)向“系統(tǒng)主動協(xié)同生成”。其核心在于界面本身成為可…

2026/7/29 1:15:28 閱讀更多
AI 電動竹火炬智能功率 MOSFET 完整選型方案

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

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

2026/7/29 1:15:28 閱讀更多
智習室避坑指南:技術(shù)適配與合規(guī)性才是核心,天學網(wǎng)實測數(shù)據(jù)揭秘

智習室避坑指南:技術(shù)適配與合規(guī)性才是核心,天學網(wǎng)實測數(shù)據(jù)揭秘

【摘要】本文基于縣域中學、公立校及教培機構(gòu)的智習室落地實戰(zhàn)經(jīng)驗,深度拆解算法適配差、數(shù)據(jù)同步滯后、合規(guī)性不足三大高頻踩坑痛點。結(jié)合天學網(wǎng)智習室系統(tǒng)的實測數(shù)據(jù)與合規(guī)資質(zhì),用真實案例說明技術(shù)匹配度遠比功能全面性重要,并提供分場景選…

2026/7/29 1:15:28 閱讀更多
SEATA AT模式:低侵入分布式事務解決方案的原理與實踐

SEATA AT模式:低侵入分布式事務解決方案的原理與實踐

1. 項目概述:為什么我們需要SEATA的AT模式? 在微服務架構(gòu)里,一個業(yè)務操作經(jīng)常需要跨多個服務、多個數(shù)據(jù)庫來完成。比如一個電商下單流程,你可能需要調(diào)用訂單服務創(chuàng)建訂單,調(diào)用庫存服務扣減庫存,再調(diào)用賬戶服…

2026/7/29 4:36:03 閱讀更多
密碼安全進階:鹽與胡椒在加密存儲中的關(guān)鍵作用

密碼安全進階:鹽與胡椒在加密存儲中的關(guān)鍵作用

1. 密碼安全的核心要素解析當我們在討論密碼安全時,大多數(shù)人第一反應就是"加密"——這確實沒錯,但遠遠不夠。就像做一道好菜,光有主料不行,還需要調(diào)味料來提升風味。在密碼學領(lǐng)域,"鹽"(Salt)和&qu…

2026/7/29 4:36:03 閱讀更多
python爬取貝殼中二手房的數(shù)據(jù)

python爬取貝殼中二手房的數(shù)據(jù)

前言:通過代碼爬取貝殼中二手房的數(shù)據(jù),以此給更多需要了解爬蟲或者二手房信息的人提供便利。 第一部分:爬取地址 1.1貝殼首頁地址 jiujiang.ke.com 第二部分:爬取數(shù)據(jù) 2.1輸入要爬多少頁 int(input(輸入一共要多少頁&#xf…

2026/7/29 4:26:03 閱讀更多
面試官大笑:“一個任務拆給 5 個 Subagent 并行跑,不比 1 個快 5 倍?“我搖頭:“快不了,還可能更慢“

面試官大笑:“一個任務拆給 5 個 Subagent 并行跑,不比 1 個快 5 倍?“我搖頭:“快不了,還可能更慢“

前兩個月,我在重構(gòu) AlgoMooc 網(wǎng)站過程中,發(fā)現(xiàn)一個問題:在 Claude Code 里把一個任務拆給 5 個 Subagent 并行跑,結(jié)果可能比 1 個 agent 從頭干到尾還慢? 大多數(shù)人的第一反應是反過來的:活是并行干的&#…

2026/7/29 0:15:24 閱讀更多