怎么判断一个数是不是2的N次方
来源:互联网 发布:java插件下载win7 编辑:程序博客网 时间:2024/04/27 14:15
题目:给定一个整数num,判断这个整数是否是2的N次方。比如,2,4,8是2的那次方,6,10不是2的N次方。
请看下面的程序:
01
public
static
bool Check1(
int
num)
02
{
03
int
i =
1
;
04
while
(
true
)
05
{
06
if
(i > num)
07
return
false
;
08
if
(i == num)
09
return
true
;
10
i = i *
2
;
11
}
12
}
不断的循环num%2,如果不等于0,return false,如果等于0,num=num/2,一直做到num=1
01
public
static
bool Check2(
int
num)
02
{
03
if
(num ==
1
)
04
return
true
;
05
else
06
{
07
do
08
{
09
if
(num %
2
==
0
)
10
num = num /
2
;
11
else
12
return
false
;
13
}
14
while
(num !=
1
);
15
return
true
;
16
}
17
}
其实这两种算法的思路都是相同的,但是第二种相对第一种更高效写,因为如果不是2的N次方,可以少循环很多次!
由于2的N次方的数二进制表示是第1位为1,其余为0,而x-1(假如x为2的N次方)得到的数的二进制表示恰恰是第1位为0,其余为1,两者相与,得到的结果就为0,否则结果肯定不为0。
01
public
static
boolean
getResult(
int
num)
02
{
03
if
(num <=
1
)
04
{
05
return
false
;
06
}
07
else
08
{
09
return
((num & (num -
1
)) ==
0
) ?
true
:
false
;
10
}
11
}
12
public
static
void
main(String[] args) {
13
System.out.println(getResult(
32
));
14
}
上面的程序多判断了一个1. 我们知道, 1是2的0次方。 1应该是符合要求的。下面修正:
01
public
static
bool floor_7(int num)
02
{
03
if
(num <= 1)
04
{
05
return
false;
06
}
07
else
08
{
09
return
((num & (num - 1)) == 0) ? true : false;
10
}
11
}
如果一个数是2的整数次幂,那么表示为二进制的时候会是这样:010000....
除了2的零次方,即1之外,这个数减一会得到:001111....
换言之得到一个前面全是0后面全是1的数,把这个数和原数做个按位与,得到:000000.....
换言之,如果一个数n,其不为1,且n-1 & n = 0,那么n就是一个2的整数次幂。因为只要他表达为二进制时存在两个1,就不会满足这条规律。所以最简判断方法就是:
1
if
( n < 0 )
2
throw
new
InvalidOperationException();
3
if
( n < 2 )
4
return
false;
5
return
n & ( n - 1 ) == 0
修正之后:
1
public
bool floor_8(int n)
2
{
3
if
(n < 0)
4
throw
new
InvalidOperationException();
5
if
(n < 2)
6
return
false;
7
return
n & (n - 1) == 0;
8
}
对数算法:
1
bool foo(int x)
2
{
3
float ret = log(x)/log(2);
4
return
abs
((int) ret - ret) <= 0.00001;
5
}
修正后:
1
public
bool floor_22(int x)
2
{
3
float ret = log(x) / log(2);
4
return
abs
((int)ret - ret) <= 0.00001;
5
}
对数算法比较有趣, 可惜, 浮点误差毕竟不是个容易避开的问题。因为浮点数不能直接比较, 所以用了一个0.00001来做尺度。这就存在了一个问题:当x很大的时候呢?我找了一个变态的数字来测试:0x10000001
结果是true。因为结果的小数部分实在是太小了。
01
static
void
Main(string[] args)
02
{
03
int
i =
int
.Parse(Console.ReadLine());
04
Console.WriteLine(IsCheck(i));
05
}
06
public
static
bool IsCheck(
int
num)
07
{
08
double
result = Math.Log(num,
2
);
09
if
(result.ToString().IndexOf(
"."
) >=
0
)
10
{
11
return
false
;
12
}
13
else
14
{
15
return
true
;
16
}
17
}
相同的问题。 只要使用了LOG, 就无法避免掉浮点数丢精度的问题。 这是没办法的事情。
01
public
static
bool floor_37(int num)
02
{
03
double result = Math.Log(num, 2);
04
if
(result.ToString().IndexOf(
"."
) >= 0)
05
{
06
return
false;
07
}
08
else
09
{
10
return
true;
11
}
12
}
所以总结了下, (x)&(x-1)的算法还没有被证明, 不知道除了0还有没有别的反例。因为毕竟这个算式没有严密的证明过程
- 怎么判断一个数是不是2的N次方
- 怎么判断一个数是不是2的n次方
- 判断一个数是不是2^N次方
- 判断一个数是不是2的n次方
- 【java】判断一个数是不是2的N次方
- 判断一个数是不是2的n次方
- 【c语言】判断一个数是不是2的n次方
- 【java】判断一个数是不是2的N次方
- 如何快速判断一个数是不是2的n次方
- 判断一个数是不是3的n次方
- 判断一个数是不是2的N次方 自己写的土算法
- 用最快的方法判断一个数是不是2的n次方
- 不用任何判断语句,不开方计算一个数是不是2的N次方
- 判断一个无符号整型,是不是2的N次方
- 查看一个数是不是2的n次方
- 查看一个数是不是2的n次方
- 判断一个整数是不是2的阶次方数
- 判断一个整数是不是2的阶次方数
- C语言移植到VS环境下的C++
- 如何查看ORACLE中正在运行的存储过程
- Companionship of Books
- SQLite vs MySQL vs PostgreSQL:关系型数据库比较
- 获取网络资源图片xml
- 怎么判断一个数是不是2的N次方
- 参加.Net培训让你不再当电脑维修工
- 大文件排序
- iOS学习之UINavigationController详解与使用(三)ToolBar
- C++小知识之指针和引用的区别(温故而知新)
- select的用法
- 微软2013编程之美传话游戏
- 为什么网站能够打开,却没有收录,快照也没有?
- salt-minion 端执行来自salt-master端的cmd.script命令报错的解决方案