算法学习笔记(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;
}