第一种考虑(乘法)
创建一个中间变量temp,初始值是1,然后进入一个循环,每次循环都让temp和目标值进行比较,如果相等,则说明目标是2的整数次幂,
如果不相等,则让temp乘以2,继续循环比较,直到temp的值大于目标整数时,说明整数不是2的整数次幂。
比如:18
1*2=2;2比18小继续
2*2=4;4比18小继续
4*2=8;8比18小继续
8*2=16;16比18小继续
16*2=32;32比18大退出循环,说明18不是2的整数幂。
如果目标整数的大小是n,则此方法循环次数是logn。
代码如下:
1 public static boolean is2Power1(intnum) {2 int temp = 1;3 while (temp <=num) {4 if (temp ==num) {5 return true;6 }7 temp = temp << 1;8 //temp = temp * 2;
9 }10 return false;11 }
想一想,有没有更好的办法?
第二种考虑(除法)
2的整数次幂都能被2整除,所以进入一个循环,让目标对2求余,如果有余数,则目标不是2的整数次幂,
如果没有余数,然后目标赋值为目标除以2,直到目标小于1,当目标小于1的时候则说明明目标是2的整数次幂。
比如:18
18%2=0;18被2整除
18/2=9;目标赋值为9
9%2=1;9没被2整除退出循环,说明18不是2的整数幂。
如果目标整数的大小是n,则此方法循环次数有可能是1,2,3,4,...logn次。
代码如下:
1 public static boolean is2Power2(intnum) {2 while (num > 1) {3 if (num % 2 == 1) {4 return false;5 }6 //num = num / 2;
7 num = num >> 1;8 }9 return true;10 }
再想一想,有没有更好的办法?
第三种考虑(位运算)
让我们看看2的整数次幂转成二进制是什么样的
十进制
二进制
是否为2的整数次幂
8
1000
是
16
10000
是
32
100000
是
64
1000000
是
100
1100100
否
是不是发现了,如果一个整数是2的整数次幂,那么当它转化成二进制时,只有最高位是1,其它位都是0!如果把这2的整数次幂各自减去1,在转换成二进制,会是什么样呢?
十进制
二进制
原数值减1
是否为2的整数次幂
8
1000
111
是
16
10000
1111
是
32
100000
11111
是
64
1000000
111111
是
100
10000000
1111111
是
是不是发现了,2的整数幂减去1时,它的二进制数字都变成1了!如果在加上&运算符会出现什么结果呢?
十进制
二进制
原数值减1
n&n-1
是否为2的整数次幂
8
1000
111
0
是
16
10000
1111
0
是
32
100000
11111
0
是
64
1000000
111111
0
是
100
10000000
1111111
1100000
是
怎么样会写代码了吗?
代码如下:
1 public static boolean is2Power3(intnum) {2 return (num & num - 1) == 0;3 }
是不是很简单,只要动用所学过的知识点,联系起来,一个问题就迎刃而解!!!