美文网首页
如何判断一个正整数是否是2的乘方

如何判断一个正整数是否是2的乘方

作者: sjyu_eadd | 来源:发表于2021-07-29 09:42 被阅读0次

    实现一个方法,判断一个正整数是否是2的乘方(比如16是2的4次方,返回True;否则返回False)

    方法一:使用该数循环除以2,如果最终商是1并且余数是0,则返回True;循环中一旦出现余数不为0,则返回False

    方法二:从1开始循环乘以2,直到结果第一次大于或者等于目标值,如果相等,则放回True,如果大于,则返回False

    方法三:借助位运算
    如果该数是2的乘方,则该数的二进制表示仅包含一个1,那么该数与他的减一的数相与,一定为0; 否则该数一定不是2的乘方。

    以数字5为例: 0000 0101 & 0000 0100 = 0000 0100
    以数字8为例 :0000 1000 & 0000 0111 = 0000 0000

    image.png

    与方法一二比较,通过该方法只需要一次运算即可得出结果

    Python代码及耗时统计如下:

    #!/usr/bin/python
    #-*- coding:utf-8 -*-
    import time
    def isPowerOf2_1(i):
        if i < 1:
            return False
        while i > 1:
            if(i % 2):
                return False
            i = i / 2
        return True
     
    def isPowerOf2_2(i):
        j = 1
        while j < i:
            j = j * 2
        if j == i:
            return True
        return False
     
    def isPowerOf2_3(i):
        if i < 1:
            return False
        if(i & (i - 1)):
            return False
        return True
    def computeNum1(i):
        num = 0
        while(i):
            num += 1
            i = i & (i - 1)
        return num
    if __name__ == "__main__":
        num = 20000000
        lst1 = list()
        start = time.time()
        for i in range(num):
            if (isPowerOf2_1(i)):
                lst1.append(i)
        end = time.time()
        print "used time: %s" % (end - start), lst1
        lst2 = list()
        start = time.time()
        for i in range(num):
            if (isPowerOf2_2(i)):
                lst2.append(i)
        end = time.time()
        print "used time: %s" % (end - start), lst2
        lst3 = list()
        start = time.time()
        for i in range(num):
            if (isPowerOf2_3(i)):
                lst3.append(i)
        end = time.time()
        print "used time: %s" % (end - start), lst3
     
        print computeNum1(142)
        print computeNum1(143)
        print computeNum1(128)
    

    运行结果

    used time: 12.3350000381 [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216]
    used time: 46.5840001106 [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216]
    used time: 7.85400009155 [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216]
    4
    5
    1
    Process finished with exit code 0
    

    拓展: 如何计算一个正整数的二进制表示含有多少个1?

    借助方法三,一个正整数N与N-1相与的结果是1的个数减一,那么我们可以不断的相与直至结果为0,就可以统计1的个数了

    142的二进制表示为1000 1110 共4个1

    第一次相与减少一个1: 1000 1110 & 10001101 = 1000 1100 N更新为1000 1100,3个1

    第二次相与减少一个1: 1000 1100 & 1000 1011 = 1000 1000 N更新为1000 1000,2个1

    第三次相与减少一个1: 1000 1000 & 1000 0111 = 1000 0000 N更新为1000 0000,1个1

    第四次相与减少一个1: 1000 0000 & 0111 1111 = 0000 0000 N更新为 0000 0000,0个1

    四次相与后,变为0,说明142有4个1

    代码实现在上面代码里函数computeNum1里

    相关文章

      网友评论

          本文标题:如何判断一个正整数是否是2的乘方

          本文链接:https://www.haomeiwen.com/subject/djsxvltx.html