神奇的位運算(不會不行啊。。。被坑了好多題了。。。。)
清零取反要用與,某位置一可用或
若要取反和交換,輕輕鬆鬆用異或
移位運算
要點 1 它們都是雙目運算子,兩個運算分量都是整形,結果也是整形。
2 " < <" 左移:右邊空出的位上補0,左邊的位將從字頭擠掉,其值相當於乘2。
3 ">>"右移:右邊的位被擠掉。對於左邊移出的空位,如果是正數則空位補0,若為負數,可能補0或補1,這取決於所用的計算機系統。
4 ">>>"運算子,右邊的位被擠掉,對於左邊移出的空位一概補上0。
位運算子的應用 (源運算元s 掩碼mask)
(1) 按位與-- &
1 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)
2 取某數中指定位 (mask中特定位置1,其它位為0,s=s&mask)
(2) 按位或-- ¦
常用來將源運算元某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s ¦mask)
(3) 位異或-- ^
1 使特定位的值取反 (mask中特定位置1,其它位為0 s=s^mask)
2 不引入第三變數,交換兩個變數的值 (設 a=a1,b=b1)
目 標 操 作 操作後狀態
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
二進位制補碼運算公式:
-x = ~x 1 = ~(x-1)
~x = -x-1
-(~x) = x 1
~(-x) = x-1
x y = x - ~y - 1 = (x ¦y) (x&y)
x-y = x ~y 1 = (x ¦~y)-(~x&y)
x^y = (x ¦y)-(x&y)
x ¦y = (x&~y) y
x&y = (~x ¦y)-~x
x==y: ~(x-y ¦y-x)
x!=y: x-y ¦y-x
x < y: (x-y)^((x^y)&((x-y)^x))
x <=y: (x ¦~y)&((x^y) ¦~(y-x))
x < y: (~x&y) ¦((~x ¦y)&(x-y))//無符號x,y比較
x <=y: (~x ¦y)&((x^y) ¦~(y-x))//無符號x,y比較
應用舉例
(1) 判斷int型變數a是奇數還是偶數
a&1 = 0 偶數
a&1 = 1 奇數
(2) 取int型變數a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
(3) 將int型變數a的第k位清0,即a=a&~(1 < <k)
(4) 將int型變數a的第k位置1, 即a=a ¦(1 < <k)
(5) int型變數迴圈左移k次,即a=a < <k ¦a>>16-k (設sizeof(int)=16)
(6) int型變數a迴圈右移k次,即a=a>>k ¦a < <16-k (設sizeof(int)=16)
(7)整數的平均值
對於兩個整數x,y,如果用 (x y)/2 求平均值,會產生溢位,因為 x y 可能會大於INT_MAX,但是我們知道它們的平均值是肯定不會溢位的,我們用如下演算法:
int average(int x, int y) //返回X,Y 的平均值
{
return (x&y) ((x^y)>>1);
}
(8)判斷一個整數是不是2的冪,對於一個數 x >= 0,判斷他是不是2的冪
boolean power2(int x)
{
return ((x&(x-1))==0)&&(x!=0);
}
(9)不用temp交換兩個整數
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
(10)計算絕對值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x y)^y
}
(11)取模運算轉化成位運算 (在不產生溢位的情況下)
a % (2^n) 等價於 a & (2^n - 1)
(12)乘法運算轉化成位運算 (在不產生溢位的情況下)
a * (2^n) 等價於 a < < n
(13)除法運算轉化成位運算 (在不產生溢位的情況下)
a / (2^n) 等價於 a>> n
例: 12/8 == 12>>3
(14) a % 2 等價於 a & 1
(15) if (x == a) x= b;
else x= a;
等價於 x= a ^ b ^ x;
(16) x 的 相反數 表示為 (~x 1)
例項
功能 ¦ 示例 ¦ 位運算
---------------------- --------------------------- --------------------
去掉最後一位 ¦ (101101->10110) ¦ x >> 1
在最後加一個0 ¦ (101101->1011010) ¦ x < < 1
在最後加一個1 ¦ (101101->1011011) ¦ x < < 1 1
把最後一位變成1 ¦ (101100->101101) ¦ x ¦ 1
把最後一位變成0 ¦ (101101->101100) ¦ x ¦ 1-1
最後一位取反 ¦ (101101->101100) ¦ x ^ 1
把右數第k位變成1 ¦ (101001->101101,k=3) ¦ x ¦ (1 < < (k-1))
把右數第k位變成0 ¦ (101101->101001,k=3) ¦ x & ~ (1 < < (k-1))
右數第k位取反 ¦ (101001->101101,k=3) ¦ x ^ (1 < < (k-1))
取末三位 ¦ (1101101->101) ¦ x & 7
取末k位 ¦ (1101101->1101,k=5) ¦ x & ((1 < < k)-1)
取右數第k位 ¦ (1101101->1,k=4) ¦ x >> (k-1) & 1
把末k位變成1 ¦ (101001->101111,k=4) ¦ x ¦ (1 < < k-1)
末k位取反 ¦ (101001->100110,k=4) ¦ x ^ (1 < < k-1)
把右邊連續的1變成0 ¦ (100101111->100100000) ¦ x & (x 1)
把右起第一個0變成1 ¦ (100101111->100111111) ¦ x ¦ (x 1)
把右邊連續的0變成1 ¦ (11011000->11011111) ¦ x ¦ (x-1)
取右邊連續的1 ¦ (100101111->1111) ¦ (x ^ (x 1)) >> 1
去掉右起第一個1的左邊 ¦ (100101000->1000) ¦ x & (x ^ (x-1))
判斷奇數 (x&1)==1
判斷偶數 (x&1)==0
例如求從x位(高)到y位(低)間共有多少個1
public static int FindChessNum(int x, int y, ushort k)
{
int re = 0;
for (int i = y; i <= x; i )
{
re = ((k >> (i - 1)) & 1);
}
return re;
}
相關推薦
神奇的位運算(不會不行啊。。。被坑了好多題了。。。。)
位運算應用口訣 清零取反要用與,某位置一可用或 若要取反和交換,輕輕鬆鬆用異或 移位運算 要點 1 它們都是雙目運算子,兩個運算分量都是整形,結果也是整形。 2 " < <" 左移:右邊空出的位上補0,左邊的位將從字頭擠掉,其值相當於乘2。
子類引用父類的靜態欄位,不會導致子類初始化
先看程式碼 // 父類 public class SuperClass { static { System.out.println("SuperClass Init!"); } public static int valu
linux安裝tomcat,jdk,上傳war包分析(不會轉載,只能直接拷貝人家看,作者見了莫怪哈)
1、下載JDK和Tomcat jdk下載地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html tomcat下載地址: http://tomc
【Spring註解驅動開發】你還不會使用@Resource和@Inject註解?那你就out了!!
## 寫在前面 > 我在 **冰河技術** 微信公眾號中發表的《[【Spring註解驅動開發】使用@Autowired@Qualifier@Primary三大註解自動裝配元件,你會了嗎?](https://mp.weixin.qq.com/s?__biz=Mzg3MzE1NTIzNA==&mi
恐怖啊,MD5已經被真實情況下破解了
http://www.win.tue.nl/hashclash/SoftIntCodeSign/HelloWorld-colliding.exe http://www.win.tue.nl/hashclash/SoftI
不會點git真不行啊.
har tid 解決 create 之前 技術分享 bsp 案例 rebase 基本使用: // 進入項目根目錄, git init // 接管你的項目文件夾, git status // 查看狀態. 綠色已接管,紅色未管理 git add . // 添加管理當前目
zoj 3432 神奇的位運算。。
不得不說。。。這個真的很神奇。。又學會一招。 #include <stdio.h> #include <string.h> char str[8]; char str1[8]; int main(void) { int n; while (scan
神奇的位運算
eof googl 去掉 www 知識點 binarys 深入理解 網上 負數 位運算的威力 前言: 在學習Java二進制各種轉換時,發現對位運算很不熟悉,怪我基礎沒打好,更要好好學習了。然後從網上搜刮了一些位運算的小應用,然後有一些不熟悉的自己用Java代碼試了一下,發
產品經理如何與強勢的技術溝通? 技術比較有資歷,會以技術無法實現等方面的原因拒絕處理產品提出的需求。 你們是否遇到這樣的技術? 產品懂技術的話,是不是會好一些,因為可以和技術說“行話”了,並且產品懂技術就不會被忽悠了。
intern 世界 自己人 做好自己 最重要的 叠代開發 對比 不一定 制造 PM在YY...作為強勢的技術來回答一下吧。說明白WHY,HOW,WHAT就好了。 我想點兩個贊,u can u up,no can no bb 什麽的。 微軟的win8之父年輕時候也是一個PM應
解決VS2013調試ASP.NET中無法調試的問題:當前不會命中斷點。在 XXXX.dll 中找到了 XXX.cs 的副本,但是當前源代碼與 XXXX.dll 中內置的版本不同。
strong 當前不會命中斷點 導致 隨機 當前日期 目錄 一次 但是 解決 解決思路: 一定是在某個文件夾存在了副本,結果果然不出所料。 當前日期是2016年3月10日,But C:\Windows\Microsoft.NET\Framework\v4.0.3
單頁面跳轉添加返回和跳轉動畫(仿app) 只對單頁面和跳轉有用,我用的是angualr,有不會的可以私信問我。
hist page func margin consola color -s tar pla p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Consolas; color: #596972 } p.p2 { mar
寫不了,不會,告辭。程序員三連(第二次站立議會)
昨天 nbsp 會議 安卓 暫時 ima view 構建 困難 目前的進度: 個人進度: 劉子琦:已經熟悉安卓開發軟件的使用,計劃最近一個站立議會完成2個頁面開發,問題目前對Android結構理解較淺 陳藝祥:初步學習了sql server,學會了建表等基本操作,計劃
Codeforces Round #267 (Div. 2) B. Fedor and New Game【位運算/給你m+1個數讓你判斷所給數的二進制形式與第m+1個數不相同的位數是不是小於等於k,是的話就累計起來】
ons ecif 否則 ans contain rst rmi sum any After you had helped George and Alex to move in the dorm, they went to help their friend
你拿著兩個雞蛋站在 100 層的大樓上。雞蛋或許結實到從樓頂掉下也不會摔破。或許很易碎,在一樓摔下就破碎。
雞蛋 可能 結果 最大 第一個 bsp 我們 需要 無法 你拿著兩個雞蛋站在 100 層的大樓上。雞蛋或許結實到從樓頂掉下也不會摔破。或許很易碎,在一樓摔下就破碎。請問最少試驗多少次可以確保找出雞蛋不會被摔碎的最高樓層? 註意:1、只有兩個蛋2、確保找出 一開始,
在將數組轉為list集合的時候,通過構造器創建集合是創建了一個引用,不會修改數組。
jpg 引用 集合 技術 pos 數組 alt .cn clas 在將數組轉為list集合的時候,通過構造器創建集合是創建了一個引用,不會修改數組。
被引用的帳戶目前被鎖定,可能不會登錄。這個問題困擾我好久,每次都要找域管理員。
是什麽 設置 管理員 閾值 密碼 但是 出現 還需 帳戶 這個問題,一直出現,而且每次都要找域administrator,他給我的用戶權限是admin的,但是我經常被鎖住,這是為什麽呢?因為怕暴力破解密碼,所以設置了10次的閾值,但是鎖定以後,就不會再解開,30分鐘過了也不
哪位大神會的能不能做一下 或咨詢一下
三層交換 交換機 路由器 pc 局域網 哪位大神會的能不能做一下 或咨詢一下
lua5.1的一個bug——不支持位運算
http 異或 mar near type per mbo .exe col 下載了luaforwindows5.1.exe文件,並按照之後,寫了一個腳本文件如下,並運行,結果出乎意料,unexpec symbol near ‘&‘。這意思是有語法錯誤。下了最新版本
一組資料中只有一個數字出現一次,其他所有數字都是成對出現的。請找出這個數。(使用位運算)
連續異或即可得到這個數 #include <windows.h> #include <sdilo.h> int find(int a[],int len) { int ret = 0; int i = 0; for (i = 0; i < len;
程式設計實現: 一組資料中只有一個數字出現了一次。其他所有數字都是成對出現的。 請找出這個數字。(使用位運算)
可以在指定陣列中找出只出現一次的元素 #include<stdio.h> int main() { int arr[] = { 1, 3, 4, 3, 1}; int i = 0; int len = sizeof(arr) / sizeof(ar