• 位运算


    位运算

    判断字节序

    问题描述:判断一台机器是大尾顺序还是小尾顺序。

        int x = 1;
        if (1 ==  *(char*)&x) {
            printf("Little endian"); 
    
        } else {
            printf("Big endian"); 
        } 

    整数的二进制中1的个数

    int BitCount(int x) {
        int cnt = 0;
        while (x) {
            x &= x - 1;
            cnt++;
        }
        return cnt;
    }

    判断是否为2的幂

    如果一个数是2的N次幂,那么它的二进制表示中只有一个1。

    bool isPowerOfTwo(int n) {
        if (n<=0) return false;
        return (n & n-1) == 0;
    }

    判断是否为3的幂

    如果是判断一个int类型是否是3的幂,在int范围内3^19=1162261467是最大的一个幂,3^20就超出了int型表示范围,

    如果一个int数是3的幂,那么它肯定也能被1162261467整除,所以:

    bool isPowerOfThree(int n) {
        if (n<=0) return false;
        return 1162261467 % n == 0;
    }

    判断是否为4的幂

    如果一个数是2的N次幂,那么它的二进制表示中只有一个1,并且在奇数位,如1,100,10000……

    bool isPowerOfFour(int num) {
        return (num > 0) && ((num & num-1) == 0) && ((num & 0xAAAAAAAA) == 0);
    }

    注意:这里不能用判断一个数是否是3的幂的方法,因为3是质数不能再分解,而4可以分解成2*2。

    反转一个字节

    首先是2位2位为一组,交换前一半和后一半。再4位4位为一组,交换前一半和后一半。再8位为一组,交换前一半和后一半。

    unsigned char reverse8( unsigned char c )
    {
         c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
         c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
         c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
         return c;
    }

    位运算实现加、减、乘、除

    先说加法,一个例子:计算5+17,5的二进制是101,17的二进制10001。还是试着把计算分成三步:

    1、各位相加但不计进位,得到的结果是10100(最后一位两个数都是1,相加的结果是二进制的10。这一步不计进位,因此结果仍然是0);
    2、记下进位。在这个例子中只在最后一位相加时产生一个进位,结果是二进制的10;
    3、把前两步的结果相加,得到的结果是10110,正好是22。
    int add(int a, int b)
    {
        if (0 == b)
            return a;
        int sum = a ^ b;
        int carry = (a & b) << 1;
        return add(sum, carry);
    }

    减法比较简单,比如a-b=a+(-b),所以只要知道怎么求相反数就可以用加法实现减法了。

    根据补码的特性,各位取反加1即可(注意得到的是相反数,不是该数的补码,因为符号位改变了)

    int negative(int a)
    {
        return add(~a, 1);
    }
    
    int sub(int a, int b)
    {
        return add(a, negative(b));
    }

    再来说乘法,比如a*b,就是b个a相加;那除法呢?比如a/b,就是a能减去多少个b;可见乘除也可以用加减法实现。

  • 相关阅读:
    selenium产生的垃圾文件清理
    英语学习词根法
    ecommerce学习
    tfs2012安装
    转载文件,英语学习
    Mishka and Divisors CodeForces
    Codeforces Round #364 (Div. 1) (差一个后缀自动机)
    莫比乌斯反演练习
    bzoj 1267 Kth Number I (点分治,堆)
    程序员的绘图利器 — Gnuplot
  • 原文地址:https://www.cnblogs.com/chenny7/p/5569943.html
Copyright © 2020-2023  润新知