1. 程式人生 > >神奇的位運算(不會不行啊。。。被坑了好多題了。。。。)

神奇的位運算(不會不行啊。。。被坑了好多題了。。。。)

位運算應用口訣
清零取反要用與,某位置一可用或
若要取反和交換,輕輕鬆鬆用異或
移位運算
要點 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,學會了建表等基本操作,計劃

你拿著兩個雞蛋站在 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