转:位运算,常见用法集

位运算神马的,最给力了,当你的复杂度优化到不能再优的时候,你还可以考虑位运算,把本来小时级别的运算提高到秒级别。

比如6400个bool值向量,你要窜位比较相似度O(n^2)复杂度不能再优化的情况下,需要6400*6400=4千万次比较,如果变成Ulong 64位的,每次O(1)比较64位,就可以把复杂度压缩到O(n^2/64/64),时间压缩4000倍!

本来小时级别的运算提高到秒级别。

参考我另外一个文章,位运算技巧总结:

http://blog.csdn.net/superdullwolf/archive/2009/10/10/4649080.aspx

下面是C#的一些实验。

using System;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//TestBitOpration();
//swap();
//Judge();
//MeanInt();
//power();
//abs();
//mod();// 没有得出正确的输出
//multi();// 不够完美
//division();
//oppo();
comple();
}
private void swap()
{
int op1 = 31, op2 = 33;
// 位运算实现交换操作
//先做出俩个整数的异或,交换时和另外一个再做次异或就可实现交换了
op1 = 31 ^ 33 ^ 31; //op1变成33
op2 = 31 ^ 33 ^ 33; //op2变成31
MessageBox.Show(Convert.ToString(op1));
MessageBox.Show(Convert.ToString(op2));
}

public void TestBitOpration()
{

//二进制位运算
int op1 = op2 = 8;//1000
op1 = op1 ^ 1; //和1做异或时,奇数减1,偶数加1 1001
op2 = op2 & 1; //都为1的才为1;0
op1 = op1 | 1; //有一个为1就为1;1001
op1 = op1 << 1; //10010
op2 = op2 << 1; //0

this.richTextBox1.AppendText(Convert.ToString(op1, 2) + "\n");
// this.richTextBox1.AppendText(Convert.ToString(op2, 2) + "\n");

/*
//提取某个整数的某一二进制位
int [] kbit=new int[sizeof(int)];
int k;
for (k = 0; k <=sizeof(int); k++)
{
kbit[k] = op1 >> k & 1;
MessageBox.Show(Convert.ToString(kbit[k]));
}
*/
//对int型变量的第3位清0or1
MessageBox.Show(Convert.ToString(op1, 2));
op1
= op1 & ~(1 << 3); //置0 向左移三位,是第四位
MessageBox.Show(Convert.ToString(op1, 2));
op1
= op1 | (1 << 3);//置1
MessageBox.Show(Convert.ToString(op1, 2));


}

private void Judge()
{
//判断奇数还是偶数
int op = 8;
string output = "";
if ((op & 1) == 0)
{
output
= "op is 偶数";
MessageBox.Show(output);
}
if ((op & 1) == 1)
{
output
= "op is 奇数";
MessageBox.Show(output);
}
}
private void MeanInt()
{
//计算整数的平均值
int mean, op1 = 8, op2 = 18;
mean
= (op1 & op2) + ((op1 ^ op2) >> 1);//还没想明白原理
MessageBox.Show(Convert.ToString(mean));

}
//判断op>0 是不是2 的整数幂
private void power()
{
int op = 18;
string output = "";
if ((op & (op - 1)) == 0)
output
= "op 是2的整数幂";
else
output
= "op 不是2的整数幂";
MessageBox.Show(output);
}
private void abs()
{
//绝对值运算,原理还没掌握
int abs, op = -18;
MessageBox.Show(Convert.ToString(op));
abs
= op >> 31;
MessageBox.Show(Convert.ToString(abs));
abs
= (op ^ abs) - abs;
MessageBox.Show(Convert.ToString(abs));
}

private void mod()
{
int a = 65, n = 3;
int c;
c
= a % (2 ^ n);
MessageBox.Show(Convert.ToString(c));
c
= a & (2 ^ n - 1);
MessageBox.Show(Convert.ToString(c));
}
private void multi()
{
int op1 = 8, n = 2;
int result;
result
= op1 * 4;
MessageBox.Show(Convert.ToString(result));
result
= op1 << n;
MessageBox.Show(Convert.ToString(result));
}
private void division()
{
int op1 = 8, n = 2;
int result;
result
= op1 / 4;
MessageBox.Show(Convert.ToString(result));
result
= op1 >> n;
MessageBox.Show(Convert.ToString(result));

}
private void oppo()
{
int op=9;
int result=(~op+1);
MessageBox.Show(Convert.ToString(op));
MessageBox.Show(Convert.ToString(result));
}
private void comple()
{
int op1=9, op2,op3,op4;
MessageBox.Show(Convert.ToString(op1,
2));
op2
= ~op1;
op3
= ~op1 + 1;
op4
= (1 >> 32) - 9;
MessageBox.Show(Convert.ToString(op2,
2));
MessageBox.Show(Convert.ToString(op3,
2));
MessageBox.Show(Convert.ToString(op3));
MessageBox.Show(Convert.ToString(
-9, 2));
MessageBox.Show(Convert.ToString(op4));
MessageBox.Show(Convert.ToString(op4,
2));
MessageBox.Show(Convert.ToString(
-2,2));
}

public static bool Is1AtKPos(ulong u, int k)
{
return ((u >> (k - 1)) & 1ul) == 1ul;
}

//判断一个ulong数字里有几个1
public static int MatchDegree(ulong u)
{
u
= (u & 0x5555555555555555) + ((u >> 1) & 0x5555555555555555);
u
= (u & 0x3333333333333333) + ((u >> 2) & 0x3333333333333333);
u
= (u & 0x0F0F0F0F0F0F0F0F) + ((u >> 4) & 0x0F0F0F0F0F0F0F0F);
u
= (u & 0x00FF00FF00FF00FF) + ((u >> 8) & 0x00FF00FF00FF00FF);
u
= (u & 0x0000FFFF0000FFFF) + ((u >> 16) & 0x0000FFFF0000FFFF);
u
= (u & 0x00000000FFFFFFFF) + ((u >> 32) & 0x00000000FFFFFFFF);
return Convert.ToInt32(u);
}

private void Form1_Load(object sender, EventArgs e)
{

}

public int op2 { get; set; }

private void richTextBox1_TextChanged(object sender, EventArgs e)
{

}
}


}
posted @ 2011-06-30 09:31  狼-志  阅读(317)  评论(0编辑  收藏  举报