算法學習筆記(5)-------位運算的tips

在計算機中全部數據都是以二進制的形式儲存的。位運算其實就是直接對在內存中的二進制數據進行操做,所以處理數據的速度很是快。ios

在實際編程中,若是能巧妙運用位操做,徹底能夠達到四兩撥千斤的效果,正由於位操做的這些優勢,因此位操做在各大IT公司的筆試面試中一直是個熱點問題。面試

如下就位運算的小訣竅進行總結供本身學習,大部分來自網上的。編程

  1. 交換兩個整數(注意:在編譯器中,針對double或float的位運算會報錯)
    學習

int swap(int &a, int &b)
{
	if (a != b)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
	return 0;
}

咱們能夠這樣理解,第一步a=a^b,第二步b=a^b=(a^b)^b=a^(b^b)=a;第三步:a=a^b=(a^b)^a=(a^a)^b=b,交換完畢,不太理解的話能夠本身寫一個數的二進制進行測試。測試

  1. 變換符號--------變換符號就是將一個數從正數變到負數,從負數變到整數優化

    例如:8-----00001000,對該數取反,爲11110111+1----11111000------ -8spa

  2. int SignReversal(int a)
    {
    	return (~a + 1);
    }

    求絕對值------
code

首先判斷這個數是不是負數,將其右移31位,獲得符號位,符號位爲-1則是負數,符號位是0則是正數。由交換符號推導可知,負數專爲整數則位取反+1內存

int abs(int a)
{
	int flag = (a >> 31);
	return (flag == 0) ? a: (~a + 1);
}

對以上的方法代碼還能夠進行優化,咱們知道,任何一個數與0亦或等於自己,與-1即0XFFFFFFFF亦或至關於位取反,再加一就是對該數交換符號。故代碼能夠以下所寫:ci

int myAbs(int a)
{
	int flag = (a >> 31);
	return ((a^flag) - flag);
}

高低位交換----------

給出一個無符號的16位數,稱這個數的前8位爲"高位",後8位爲"低位", 要求將這個數的"高位"轉爲"低位",「低位」轉爲「高位」。假設這個數的16位爲x1x2x3x4x5x6x7x8 y1y2y3y4y5y6y7y8,將其位右移8位,則高位自動補0,結果爲00000000 x1x2x3x4x5x6x7x8,再將該數位左移8位,其低位自動補0,y1y2y3y4y5y6y7y8 00000000,將這兩個結果亦或便可將高低位交換,代碼以下:

#include<iostream>
#include<string>
using namespace std;
template <class T> 
void printBinary(T a)
{
	for (int i=sizeof(a)*8-1; i>=0; i--)
	{
		if ((a >> i) == 1)
			cout <<'1';
		else 
			cout << '0';
		if (i == (sizeof(a)*8-1)/2+1)
			cout <<' ';
	}
	cout << endl;
}

int main()
{
	unsigned short a;
	unsigned short b;
	cin >> a;
	b = ((a>>8)|(a<<8));
	printBinary(a);
	printBinary(b);
	return 0;
}
相關文章
相關標籤/搜索