一个数是否为2的次幂的问题

判断一个数是否为2的次幂

判断一个数是否2的次幂的方法:

(n & n - 1) == 0

因为如果一个数是2的次幂,则它对应的二进制数中只有一个1, 如果将这个数减1,则这个仅有的1会变成0,而它的低位则会变成1。所以,将这个数与减去1的数进行与运算后就会为0。

unsigned int IsPowerOfTwo(unsigned int n)
{
    if ((n & n-1) == 0) {
        return 1;
    }
    return 0;
}

计算大于或等于某个值的最小的2次幂

问题:计算大于或等于某个值的最小的2次幂。比如给定一个数12,则输出16。给定5、6、7,则会输出8。给定1,则输出1(1是2的0次幂)。

下面是两种常规的做法:

方法一:

#define MAX_POW_TWO (((size_t) 1) << 31)

unsigned int NextPowerOfTwo(unsigned int n)
{
    if (n >= MAX_POW_TWO) {
        return MAX_POW_TWO;
    }
    if (n <= 1) {
        return 1;
    }
    unsigned int result = 1;
    while (1) {
        if (result >= n) {
            return result;
        }
        result <<= 1;
    }
}

方法二:

unsigned int NextPowerOfTwo1(unsigned int n)
{
    if (n >= MAX_POW_TWO) {
        return MAX_POW_TWO;
    }
    if (n <= 1) {
        return 1;
    }

    unsigned int i = 0;
    for (--n; n > 0; n >>= 1) {
        i++;
    }
    return 1 << i;
}

今天看到另外一种算法,感觉很高级。这里记录一下。

方法三:

unsigned int upper_pow_two(unsigned int n)
{
    if (n >= MAX_POW_TWO)
        return MAX_POW_TWO;

    if (n <= 1)
        return 1;

    n--;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    n++;
    return n;
}

求某个值离它最近的2的次幂

那如果不是求大于或等于这个数的2的次幂,而是求它离的最近的数呢? 比如10, 第一个小于它的数是8,第一个大于它的数是16。因为8离10更近,所以输出是8.那这个算法该怎么写呢?其实稍微修改上面的函数即可:

unsigned int nearestPowerOfTwo(unsigned int n)
{
    if (n >= MAX_POW_TWO)
        return MAX_POW_TWO;

    if (n <= 1)
        return 1;

    int v = n; 

    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++; // v++之后就是大于这个数的2的次幂

    int x = v >> 1; // x是小于这个数的2的次幂

    return (v - n) > (n - x) ? x : v;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值