代码改变世界

位运算技巧4

2013-09-03 21:48  youxin  阅读(535)  评论(0编辑  收藏  举报

位运算进制转换:

要求:分别实现十进制整数按二进制、十六进制输出。

两种方法实现按二进制输出:

方法1:由于整数在计算机中是按二进制存储的,我们只需要将其每个bit按顺序打印出来即可,如果某位为1,则打印字符‘1’,否则打印字符‘0’。我给出的代码如下:

void printBinary(int num)

{ 

    for(int i=0;i<32;i++)

    {

       cout<<((num>>(31-i))&1);

        //cout<<( (num &(1<<(31-i))) ==0? 0 : 1 );

    }

}

 

其中被注释掉的那个cout与没注释的cout有同样的功能!这个函数的思路很简单,就是从高到底逐位打印每个bit。我上面的代码有一点不好的地方,那就是语句太复杂,一个cout语句干了太多的事情,如果影响您的理解,那么你可以增加几个临时变量,然后把它拆分成多个简单语句。我这么写主要是考虑到篇幅的原因,因此程序段太占篇幅了。随便说一句,编程时,语句力求简单明了:一行只写一条语句,一条语句只干一件事情!

 

方法二:利用bitset来实现

bitset是标准库提供的一个类(不是容器),利用它就可以很方便地操作位,下面是用bitset来实现的程序:

void printBinary2(int num)
{
    bitset<32> bits(num);
    for(int i=31;i>=0;i--)
    {
        cout<<(bits[i]==true?'1':'0');
    }
}

 

实现按16进制输出:

同样由于数据在内存中是按二进制存储的,因此将整数按照16进制输出我们可以如下做:从左向右,每4位bit一组,组合成一个十六进制数,一次输出即可,其程序如下:

void printHex(int num)
{
    for(int i=28;i>=0;i-=4)
    {
        int tmp=num>>i;
        tmp=tmp&15; //15是掩码,为什么,不要这个则错误
        char ch;
        tmp>9?(ch='A'+tmp-10):(ch='0'+tmp);
        cout<<ch;
    }
}
    

为什么要有

 tmp=tmp&15; //15是掩码,为什么,不要这个则错误
因为在后面我们》》4或者其他时,由于右边的数有些干扰,我们用15也就是1111去掩盖掉。因为每次只取4位。

该程序与上面的printBinary函数非常相似,要注意的是i每次变化4,最关键点在于语句temp= temp&15;由于是16进制,因此这里用15做掩码。我想有了printBinary做铺垫,理解这个printHex并不难,这里不赘述了。接下来我将对这两个函数进行个小小的扩展:实现整数按2n (2的n次方)进制输出!比如按8进制,32进制等。为了方便描述,我们限制1<=n<=6;并用字符’0’到’9’表示数字0到9,用字符A,B,……Z,a,b,……表示数字10到63。程序如下:

void print2powerN(int num,int N)

{

    for(inti=32-N;i>=0;i-=N)

    {

        int temp =num>>i;

        temp =temp&((1<<N)-1);

        char ch;

       if(temp<=9)

        {

            ch ='0'+temp;

        }

        elseif(temp<=35)

        {

            ch ='A'+temp-10;

        }

        else

        {

            ch = 'a'+temp - 36;

        }          

       cout<<ch;

    }

}

 

备注:用位运算也能实现十进制到任意进制的转换,这个问题比较难,我暂时还没弄透彻!