`
rein07
  • 浏览: 21249 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

判断一个整数是否是2的N次方

阅读更多
题目:给定一个整数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!

好吧你赢了。
分享到:
评论

相关推荐

    判断一个整数是否是2的N次幂实现方法

    以上这篇判断一个整数是否是2的N次幂实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。 您可能感兴趣的文章:C语言判断一个数是否是2的幂次方或4的幂次方如何判断一个...

    js 判断一个数字是不是2的n次方幂的实例

    下面小编就为大家分享一篇js 判断一个数字是不是2的n次方幂的实例,具有很好的参考价值,希望对大家有所帮助

    Python入门程序 函数应用(判断素数、递归求n的阶乘、x的n次方、最大最小值、插入排序法)

    Python入门程序 函数应用(判断素数、递归求n的阶乘、x的n次方、最大最小值、插入排序法) 1.判断素数 #编写函数,判断一个数是否是素数。 def isprime(n): if n==1: return False for i in range(2, n): if n ...

    如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?

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

    C++和python实现阿姆斯特朗数字查找实例代码

    如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数。 例如1^3 + 5^3 + 3^3 = 153。 1000以内的阿姆斯特朗数: 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407 2.判断一个数是否为阿姆斯特朗数 1....

    水仙花数c语言程序.pdf

    在上述示例代码中,我们定义了一个`isArmstrong`函数,用来判断一个整数是否为水仙花数。该函数首先计算出该整数的位数,然后依次取各个位上的数字,并将其n次方加到sum变量中。最后,判断sum是否等于该整数,如果...

    Leetcode 326:3的幂

    给定一个整数,写一个函数来判断它是否是 3 的幂次方。 示例 1: 输入: 27 输出: true 示例 2: 输入: 0 输出: false 示例 3: 输入: 9 输出: true 示例 4: 输入: 45 输出: false 解题思路:   找出数字 n 是否是数字...

    LeetCode判断字符串是否循环-rockblog:一个私人博客

    LeetCode判断字符串是否循环 算法中常用的位运算 ...n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。 如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。 示例 1:

    Python素数检测的方法

    本文实例讲述了Python素数检测的方法...如果n是一个素数,a是小于n的任意正整数,那么a的n次方与a模n同余 实现方法: 选择一个底数(例如2),对于大整数p,如果2^(p-1)与1不是模p同余数,则p一定不是素数;否则,则p很

    delphi 开发经验技巧宝典源码

    0165 判断字符是否可以转换成整数 108 0166 判断字符中是否有汉字 108 0167 判断字符中是否有双字节 109 0168 判数输入的字符串是否为整数 109 5.4 字符串的个数问题 110 0169 获取文字中英文单词的个数...

    C语言学习实例220例

    001 第一个C程序 002 运行多个源文件 003 求整数之积 004 比较实数大小 005 字符的输出 006 显示变量所占字节数 007 自增/自减运算 008 数列求和 009 乘法口诀表 010 猜数字游戏 011 模拟ATM(自动柜员机)界面 012 ...

    4的幂(python)1

    4 的幂给定一个整数,写一个函数来判断它是否是 4 的幂次方。否则,返整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x示例 1:输入:n =

    python求解水仙花数的方法

    一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。 #!/usr/bin/python def get_flower(n, ofile): D_pow=[pow(i,n) for i in range(0,10)] V_min=1*pow(10,n-1) V_max...

    30个C#小程序学习C#的基

    30个C#小程序: c#.net常用函数和方法集 C#对注册表的操作 choosesubject ...实现一个数的N次方 输出素数 输出随机数 输出图形 宿舍值日 验证概率 一到一百之间的素数 以二进制读取文本文件 朦胧诗

    Java面试 Java超级经典100问题 Java高级开发工程师必备 Java面试宝典

    判断一个栈是否是另一个栈的弹出序列23.层序遍历二叉树。24.后序遍历二叉搜索树。25.二叉树中和为某值的路径.26.复杂链表的复制27.二叉搜索树转换为双向链表.28.打印字符串中所有字符的排列29.数组中出现次数超过...

    《剑指Offer》题目及代码.zip

    22. 判断一个栈是否是另一个栈的弹出序列 23. 层序遍历二叉树 24. 后序遍历二叉搜索树 25. 二叉树中和为某值的路径 26. 复杂链表的复制 27. 二叉搜索树转换为双向链表 28. 打印字符串中所有字符的排列 29. ...

Global site tag (gtag.js) - Google Analytics