题目:给定一个整数num,判断这个整数是否是2的N次方。比如,2,4,8是2的那次方,6,10不是2的N次方。

请看下面的程序:

public static bool Check1(int num)

{
    int i = 1;
    while (true)
    {
        if (i > num)
            return false;
        if (i == num)
            return true;
        i = i * 2;
    }
}
不断的循环num%2,如果不等于0,return false,如果等于0,num=num/2,一直做到num=1

public static bool Check2(int num)
{
    if (num == 1)
        return true;
    else
    {
        do
        {
            if (num % 2 == 0)
                num = num / 2;
            else
                return false;
        }
        while (num != 1);
        return true;
    }
}
其实这两种算法的思路都是相同的,但是第二种相对第一种更高效写,因为如果不是2的N次方,可以少循环很多次!

由于2的N次方的数二进制表示是第1位为1,其余为0,而x-1(假如x为2的N次方)得到的数的二进制表示恰恰是第1位为0,其余为1,两者相与,得到的结果就为0,否则结果肯定不为0。

public static boolean getResult(int num)
{
    if (num <= 1)
    {
        return false;
    }
    else
    {
        return ((num & (num - 1)) == 0) ? true : false;
    }
}
public static void main(String[] args) {
    System.out.println(getResult(32));
}
上面的程序多判断了一个1. 我们知道, 1是2的0次方。 1应该是符合要求的。下面修正:

public static bool floor_7(int num)
{
    if (num < 1)
    {
        return false;
    }
    else
    {
        return ((num & (num - 1)) == 0) ? true : false;
    }
}
如果一个数是2的整数次幂,那么表示为二进制的时候会是这样:010000....

除了2的零次方,即1之外,这个数减一会得到:001111....

换言之得到一个前面全是0后面全是1的数,把这个数和原数做个按位与,得到:000000.....

换言之,如果一个数n,其不为1,且n-1 & n = 0,那么n就是一个2的整数次幂。因为只要他表达为二进制时存在两个1,就不会满足这条规律。所以最简判断方法就是:

if ( n < 0 )
throw new InvalidOperationException();
if ( n < 2 )
return false;
return n & ( n - 1 ) == 0
修正之后:

public bool floor_8(int n)
{
    if (n < 0)
        throw new InvalidOperationException();
    if (n < 2)
        return false;
    return n & (n - 1) == 0;
}
对数算法:

bool foo(int x)
{
    float ret = log(x)/log(2);
    return abs((int) ret - ret) <= 0.00001;
}
修正后:

public bool floor_22(int x)
{
    float ret = log(x) / log(2);
    return abs((int)ret - ret) <= 0.00001;

}
对数算法比较有趣, 可惜, 浮点误差毕竟不是个容易避开的问题。因为浮点数不能直接比较, 所以用了一个0.00001来做尺度。这就存在了一个问题:当x很大的时候呢?我找了一个变态的数字来测试:0x10000001

结果是true。因为结果的小数部分实在是太小了。

static void Main(string[] args)
{
    int i = int.Parse(Console.ReadLine());
    Console.WriteLine(IsCheck(i));
}
public static bool IsCheck(int num)
{
    double result = Math.Log(num, 2);
    if (result.ToString().IndexOf(".") >= 0)
    {
        return false;
    }
    else
    {
        return true;
    }

}
相同的问题。 只要使用了LOG, 就无法避免掉浮点数丢精度的问题。 这是没办法的事情。

public static bool floor_37(int num)
{
    double result = Math.Log(num, 2);
    if (result.ToString().IndexOf(".") >= 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}
所以总结了下, (x)&(x-1)的算法还没有被证明, 不知道除了0还有没有别的反例。因为毕竟这个算式没有严密的证明过程。

因此我觉得, 最保险的还是位运算, 看多少个1, 来的最实在。当然这里存在一个负数的问题。第一位是1, 剩下全是0的问题。 不过有一位聪明的回复者提供了一个很强大的方法来避开负数的用例:他给参数定的类型是uint!

推荐:http://www.nowamagic.net/librarys/veda/detail/1031

如何判断一个数是否为2的N次方相关推荐

  1. 快速判断一个数是否是4的幂次方,若是,并判断出来是多少次方! .

    将4的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1(1在奇数位置),并且1后面跟了偶数个0: 因此问题可以转化为判断1后面是否跟了偶数个0就可以了. 4的整数次幂的二进制数都为 ...

  2. 快速判断一个数是否是2的幂次方

    public class Test {public static void main(String[] args) {int num = 10;if (0 == (num & (num - 1 ...

  3. 快速判断一个数是否是2的幂次方,若是,并判断出来是多少次方!

    将2的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1,并且1后面跟了n个0: 因此问题可以转化为判断1后面是否跟了n个0就可以了. 如果将这个数减去1后会发现,仅有的那个1会变为 ...

  4. 如何判断一个数是否为2的幂次方

    最近在OJ上做题,遇到一道题,其中一个细节就是需要判断一个数是否为2的幂次方.初看似乎很简单,可我想来想去,竟然无甚好办法.最后我用一个笨办法解决了,那就是将2 4 8 16 32- -存到一个数组里 ...

  5. C语言编程判断是否为2的幂,C语言判断一个数是否是2的幂次方或4的幂次方

    快速判断一个数是否是2的幂次方,若是,并判断出来是多少次方!将2的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1,并且1后面跟了n个0: 因此问题可以转化为判断1后面是否跟了n个 ...

  6. 在C语言中如何判断一个数是不是2的幂次方,判断一个数是否为2的幂次方的方法...

    对于如何判断一个数是否为2的幂次方这个问题是很多新手们都好奇的,今天我们就带着这个疑问跟小编去看看判断一个数是否为2的幂次方的方法吧,感兴趣的小伙伴们赶紧收藏起来. 将2的幂次方写成二进制形式后,很容 ...

  7. C语言判断是不是2的幂次方,C语言判断一个数是否是2的幂次方或4的幂次方

    快速判断一个数是否是2的幂次方,若是,并判断出来是多少次方! 将2的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1,并且1后面跟了n个0: 因此问题可以转化为判断1后面是否跟了n ...

  8. 随笔-如何判断一个数是否是2的n次方O(1)算法

    题目: 如何判断一个数是否是2的n次方,要求时间复杂度为O(1); 思路:本题考察的是位运算,尤其是对二进制的理解:当一个数为2的n 次方时,整个二进制数,只有他本位是1 其他位为0,如果我们给这个数 ...

  9. c语言判断一个数是否为质数的n次方,C语言中 输入一个数 判断这个数是否为3的N次方 求代码...

    C语言中 输入一个数 判断这个数是否为3的N次方 求代码 答案:4  信息版本:手机版 解决时间 2019-10-03 18:55 已解决 2019-10-03 01:54 C语言中 输入一个数 判断 ...

最新文章

  1. Symfony4中文文档: 安装和设置Symfony框架
  2. setTimeout(fn,0)
  3. linux arm ffmpeg configure文件,ffmpeg库的交叉编译记录
  4. oracle清除bin,Oracle recyclebin详解(闪回删除的表)
  5. MySQL中的执行计划(explain)
  6. MariaDB -- 数据类型
  7. pom文件各标签解释
  8. WindowsXP相关设置对应的注册表位置
  9. 2.4G射频电路设计参考(wifi ble)
  10. 崂山道士、Harry Potter和人脸识别
  11. 前端实现AWS s3亚马逊云储存上传资源
  12. idea中java版本设置
  13. python批量数据处理脚本——批量删除文件
  14. 批量微信过滤软件 开通微信号码筛选
  15. 现实世界的模型与理论
  16. C#合并多个pdf到一个pdf文件;不使用Aspose.pdf.dll,避免水印
  17. JXLS导出Excel表格实战教程
  18. 毛球科技|区块链如何改变商业生活
  19. c语言遍历 json字符串,全面详解c语言使用cJSON解析JSON字符
  20. 源代码和目标代码之间的区别

热门文章

  1. 微信小程序输入框的一些问题
  2. 微积分基本公式(牛顿——莱布尼茨公式)的几何解释
  3. 读阮一峰的React 入门实例教程有感
  4. 通过java代码实现对json字符串的格式美化(完整版)
  5. win10系统如何将硬件加速改为显卡运行速度?
  6. 零成本创业项目:豆瓣小组吸粉投放广告自动赚钱
  7. 阿里云物联网配置实例_云音箱-MQTT服务器-业务服务器三者数据流转
  8. openstack——Neutron基本架构详解
  9. 【Java问题】全网无法解决你的的IDEA中文乱码问题,不妨来看这篇文章
  10. iphone7测试cpu的软件,苹果iPhone 7的A10四核处理器性能测试:安卓机皇全都败退