练习_2_位运算

来源:互联网 发布:java oracle sql分页 编辑:程序博客网 时间:2024/04/26 23:14

1   反转一个字符的顺序

unsigned char ReverseBitsInChar03(unsigned char Num)
{
   unsigned char newNum = 0x0;

   for(int i=0;i<8;i++)
   {
       newNum<<==1;

       newNum |= Num & 0x01;
       Num>>=1;
       printf("newNum 0x%x\n", newNum);
   }

   return newNum;
}


unsigned char ReverseBitsInChar03(unsigned char Num)
{
    printf("newNum 0x%x\n", Num);
    Num = (Num&0xF0)>>4 | (Num&0x0F)<<4;
    printf("newNum 0x%x\n", Num);
    Num = (Num&0xCC)>>2 | (Num&0x33)<<2;
    printf("newNum 0x%x\n", Num);
    Num = (Num&0xAA)>>1 | (Num&0x55)<<1;
    printf("newNum 0x%x\n", Num);

    return Num;
}


2   取出float 中的小数位和整数位

void main(void)
{
    float  test_a = -0.25;

    int* temp = (int*) &test_a;
    printf("0x%x\n", *temp);

    //取出8bit的幂指数
    int e = (((*temp)>>23) & 0xff);
    printf("0x%x\n", e);

    //取出23bit有效位
    int m = (e >= 0)?(((*temp) & 0x7fffff) << 1):(((*temp) & 0x7fffff) | 0x800000);
    printf("0x%x\n", m);
}


3   16进制与float互相转换
void main(void)
{
    unsigned char blist[4];  
    float fTemp = 0.01;  
    unsigned char *bTemp = (unsigned char *)&fTemp;

    blist[0] = *bTemp;  
    blist[1] = *(bTemp+1);  
    blist[2] = *(bTemp+2);  
    blist[3] = *(bTemp+3);

    printf("%X%X%X%X\n", blist[0], blist[1], blist[2],blist[3] );
    blist[0]=0x0A;
    blist[1]=0xD7;
    blist[2]=0x23;
    blist[3]=0x3C;

    float number;
    number = *(float *)blist;

    printf("%f",number);
}


4  对float变量取绝对值

#define INV_SIGN_BIT 0x7fffffff //用来反转符号位

float Fabs_and(float fNum)
{
    int* temp = (int*)&fNum;
    int out = *temp & INV_SIGN_BIT;
    return *((float*)&out);
}
//注:这里将float转化成int的原因是C语言不支持float的移位操作。

inline float Fabs_shift(float fNum)
{
    unsigned int* temp = (unsigned int*)&fNum;
    unsigned int out = *temp;

    out = out << 1;
    out = out >> 1;

    return *((float*)&out);
}

//这里使用unsigned int的原因是C语言的移位操作对有符号数是算术移位,

//对无符号数是逻辑移位。而我们需要的是逻辑移位


5  int求绝对值

int Abs_bit(int iNum)
{
    int out = iNum;
    int temp = iNum;
    temp = temp >> 31;

    printf("0x%X\n", temp);

    out = out ^ temp;
    out = out - temp;

    return out;
}

如果iNum是正数:
     temp = temp >> 31; //temp = 0
     out = out ^ temp; //与0异或不变
     out = out - temp; //减0不变
 
out的结果就是iNum,即正数的绝对值是其本身,没问题
 
如果iNum是负数:
     temp = temp >> 31; //temp = oxffffffff
     out = out ^ temp; //out为iNum求反
     out = out - temp; // 此时temp = 0xffffffff = -1, 所以out = out + 1
把一个负数的补码连符号位求反后再加1,就是其绝对值了。比如对于-2来说:

原码 反码补码补码全求反再加1备注1000001011111101 111111100000000100000010 

大家可以看到第一个与最后一个数只有符号位不同,也就实现了求其绝对值。


比较两个整数的大小,不使用> ,  <, if语句。


int compare(int a,int b)
{
    a^=(1<<31); b^=(1<<31);
    
    int i = 31;
    while((i^-1) && !((a&(1<<i))^(b&(1<<i))))     
        i--;

    return (i^-1)?(((a>>i)&1) ? 1 : -1) : 0;
}

int main(void)
{
    int c;

    c = compare(-5, -100);
    std::cout<<c<<std::endl;

    return 0;
}






原创粉丝点击