Bitwise Operation
来源:互联网 发布:unity3d手机游戏大全 编辑:程序博客网 时间:2024/06/05 20:46
Bitwise operator in C/C++
歡迎來到二進位的世界。電腦資料都是以二進位儲存,想當然程式語言的變數也都是以二進位儲存。在 C/C++ 當中有幾個位元運算子: << SHIFT LEFT 、 >> SHIFT RIGHT 、 & AND 、 | OR 、 ^ XOR 、 ~ NOT ,可以對變數進行位元運算。接下來要介紹位元運算的一些用途。
<< SHIFT LEFT>> SHIFT RIGHT
這兩個運算子的功能主要是移動一個變數中的所有位元,位元向左 / 向右移動之後,最高位 / 最低位的位元會消失,最低位 / 最高位的位元補 0 :
5 << 1 = 10 // 00101 的全部位元向左移動一位數變成 01010。5 << 2 = 20 // 00101 的全部位元向左移動兩位數變成 10100。5 >> 1 = 2 // 00101 的全部位元向右移動一位數變成 00010。5 >> 2 = 1 // 00101 的全部位元向右移動一位數變成 00001。
在十進位當中,當全部位數向左移動一位時,數值大小會變成原來的十倍,向左移動兩位時,會變成原來的百倍。這種情形在二進位也是成立的,當全部位元向左移動一位時,會變成原來的兩倍,向左移動兩位時,會變成原來的四倍。至於往右移動也是類似道理,變成了除法而已。
由於電腦進行位元運算比乘法、除法運算快上許多,所以有很多專業的程式設計師,會利用位元運算來取代乘法、除法運算。優點是程式執行效率增加,缺點是程式碼可讀性變低:
int n = 5;n = n >> 1; // 即是 n = n / 2 之意。/* 該式子也可寫成 n >>= 1 或 n /= 2。 */
& AND
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
& 的功能是將兩個變數對應的位元進行 AND 邏輯運算,然後產生新變數。
00000000000000000000000001110100 -> 116 & 00000000000000000000000000101001 -> 41 ---------------------------------- 00000000000000000000000000100000 -> 32
& 的特色,就是可以判斷出位元是不是 1 。例如我們想要數一個變數有幾個位元是 1 :
int count_bit_1(int n){ // 由右往左看n的每一個位元。 int c = 0; for (int i=0; i<32; ++i) // int變數有32個位元 if (n & (1 << i)) c++; return c;}int count_bit_1(int n){ // 一樣是由右往左,但是每次都刪掉n的最左邊位元。 int c = 0; for (; n; n>>=1) if (n & 1) c++; return c;}
| OR
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
| 的功能是將兩個變數對應的位元進行 OR 邏輯運算,然後產生新變數。
00000000000000000000000001110100 -> 116 | 00000000000000000000000000101001 -> 41 ---------------------------------- 00000000000000000000000001111101 -> 125| 的特色,就是把位元強制標記成 1 。例如我們想要把五位數標成 1 :
int mark_5th_bit(int n){ return n | (1 << 4);}
^ XOR
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
^ 的功能是將兩個變數對應的位元進行 XOR 邏輯運算,然後產生新變數。
00000000000000000000000001110100 -> 116 ^ 00000000000000000000000000101001 -> 41 ---------------------------------- 00000000000000000000000001011101 -> 93^ 的特色,就是把位元的 0 和 1 顛倒。例如我們想要顛倒第五位數:
int reverse_5th_bit(int n){ return n ^ (1 << 4);}
~ NOT
~ 0 = 1
~ 1 = 0
~ 的功能是顛倒一個變數每一個位元的 0 和 1 。
~ 00000000000000000000000000000011 -> 3 ---------------------------------- 11111111111111111111111111111100 -> -4
Bitwise Trick
交換兩個 int 變數
void swap(int& x, int& y){ x = x ^ y; y = x ^ y; x = x ^ y;}void swap(int& x, int& y){ x ^= y ^= x ^= y;}
判斷一個整數是不是 2 的次方
bool ispow2(int n){ return (n & -n) == n;}
整數加一與減一
// 注意:比直接加一和減一還要慢。void add_one(int& x){ return -~x; // ++x}void sub_one(int& x){ return ~-x; // --x}
整數變號
void negative(int& x){ return ~x + 1; // -x;}void negative(int& x){ return (x ^ -1) + 1; // -x;}
判斷一整數是偶數還是奇數
// 若回傳true則為偶數,false則為奇數bool even_or_odd(int& x){ return x & 1; // x % 2;}
非負整數取模數,模數是二的冪次方。
int mod(int& x, int& m) // m是二的冪次方{ return x & (m - 1); // x % m;}
整數取絕對值
int abs(int& x){ // x < 0 ? -x : x; return (x ^ (x >> 31)) - (x >> 31);}
平方根倒數
3D 繪圖經常用到的一個運算,原理是牛頓法。
http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
Fast Inverse Square Root// 1.0 / sqrt(x)float InvSqrt(float x){ float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; x = x*(1.5f-xhalf*x*x); return x;}
計算 32 位元整數有幾個位元是 1
void count_bits(int& x){ x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1); x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2); x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4); x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8); x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);}
顛倒 32 位元整數的位元順序
void reverse_bits(int& x){ x = ((x >> 1) & 0x55555555) | ((x << 1) & 0xaaaaaaaa); x = ((x >> 2) & 0x33333333) | ((x << 2) & 0xcccccccc); x = ((x >> 4) & 0x0f0f0f0f) | ((x << 4) & 0xf0f0f0f0); x = ((x >> 8) & 0x00ff00ff) | ((x << 8) & 0xff00ff00); x = ((x >> 16) & 0x0000ffff) | ((x << 16) & 0xffff0000);}
32 位元整數的最高位位元位置
原理是 Binary Search 。
void highest_bit_position(int x){ x--; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x++; return x;}
- Bitwise Operation
- Bitwise Operation Explained
- Bitwise Operation Explained
- Bitwise Operation及用处
- Bitwise operation and usage
- hdu 4016 Magic Bitwise And Operation 搜索
- HDU 4016 Magic Bitwise And Operation
- HDU 4016 Magic Bitwise And Operation
- [搜索] hdu 4016 Magic Bitwise And Operation
- hdu 4016 Magic Bitwise And Operation(dfs)
- HDU 4016 Magic Bitwise And Operation (暴搜)
- Hdu 4016 Magic Bitwise And Operation
- HDU 4016 Magic Bitwise And Operation 暴搜+剪枝
- Hdu 4016 Magic Bitwise And Operation (暴搜 dfs)
- 【收集向】位操作技巧 bitwise operation trick
- HDU 4016 Magic Bitwise And Operation(dfs+剪枝)
- 解题报告:HDU_4016 Magic Bitwise And Operation 简单dfs
- one way of bitwise operation of C using struct
- 洛谷P3672(排列计数dp)
- algorithm
- LeetCode 54. Spiral Matrix
- css之display:inline-block与float区别
- 字符串全组合
- Bitwise Operation
- HDU-6214 Smallest Minimum Cut(最大流)
- Tensorflow-图像标签问题
- Qt之打包发布(NSIS详解)
- SpringCloud(第 008 篇)电影微服务,使用 application.yml 配置文件配置 Ribbon 在客户端进行负载均衡调度算法
- HDU 6215 Brute Force Sorting [链表]
- 索引的实现原理
- BZOJ 3262 陌上花开
- C#中控件Control的Paint事件和OnPaint虚函数的区别