Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中查找大于或等于n的2的最小幂_Python - Fatal编程技术网

在Python中查找大于或等于n的2的最小幂

在Python中查找大于或等于n的2的最小幂,python,Python,在Python中,返回大于或等于给定非负整数的最小2次方的最简单函数是什么 例如,大于或等于6的2的最小幂是8。总是返回2**(x-1)。bit_length()是不正确的,因为尽管它为x=1返回1,但为x=0返回非单调的2。对于x=0,单调安全的简单修复是: def next_power_of_2(x): return 1 if x == 0 else 2**(x - 1).bit_length() 样本输出: >>> print(', '.join(f'{x}

在Python中,返回大于或等于给定非负整数的最小2次方的最简单函数是什么

例如,大于或等于6的2的最小幂是8。

总是返回
2**(x-1)。bit_length()
是不正确的,因为尽管它为x=1返回1,但为x=0返回非单调的2。对于x=0,单调安全的简单修复是:

def next_power_of_2(x):  
    return 1 if x == 0 else 2**(x - 1).bit_length()
样本输出:

>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16
>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16
>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16

可以迂腐地说,x=0应该返回0(而不是1),因为
2**float('-inf')==0

这对您有用吗:

import math

def next_power_of_2(x):
    return 1 if x == 0 else 2**math.ceil(math.log2(x))
请注意,
math.log2
在Python3中可用,但在Python2中不可用。使用它而不是
math.log
可以避免后者在2**29及以上的数值问题

样本输出:

>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16
>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16
>>> print(', '.join(f'{x}:{next_power_of_2(x)}' for x in range(10)))
0:1, 1:1, 2:2, 3:4, 4:4, 5:8, 6:8, 7:8, 8:8, 9:16
可以迂腐地说x=0应该返回0(而不是1),因为
2**float('-inf')==0
让我们测试一下:

import collections
import math
import timeit

def power_bit_length(x):
    return 2**(x-1).bit_length()

def shift_bit_length(x):
    return 1<<(x-1).bit_length()

def power_log(x):
    return 2**(math.ceil(math.log(x, 2)))

def test(f):
    collections.deque((f(i) for i in range(1, 1000001)), maxlen=0)

def timetest(f):
    print('{}: {}'.format(timeit.timeit(lambda: test(f), number=10),
                          f.__name__))

timetest(power_bit_length)
timetest(shift_bit_length)
timetest(power_log)
对于Python.org Python 3.3.0:

6.566169916652143: power_bit_length
3.098236607853323: shift_bit_length
9.982460380066186: power_log
使用pypy 1.9.0/2.7.2:

2.8580930233: power_bit_length
2.49524712563: shift_bit_length
3.4371240139: power_log
我相信这表明
2**
是这里的慢部分;使用
bit_length
而不是
log
确实可以加快速度,但使用
1

对于16位整数。

我们可以使用位操作如下所示:

def next_power_of_2(n):
    if n == 0:
        return 1
    if n & (n - 1) == 0:
        return n
    while n & (n - 1) > 0:
        n &= (n - 1)
    return n << 1

要进一步阅读,请参阅。

嗯,我知道这个问题很老,我的答案也很简单,但我真的很惊讶一直没有人把它贴在这里,所以我会把它作为答案贴出来

最简单的解决方案非常简单,不需要导入任何库,如果在使用
的同时使用
语句,就可以在一个循环中完成

所以逻辑非常简单,创建一个值为1的变量,当变量的值小于数字时,将变量乘以2

代码:

这可以很容易地修改,以计算下一个电源柜到其他一些基准:

def nextpower(num, base):
  i = 1
  while i < num: i *= base
  return i
def nextpower(num,base):
i=1
而i
对于大型
x
,速度不是很慢吗?除此之外,我不能说我理解它。@delnan——你为什么认为这会很慢?(我也不理解代码…@delnan:First,
bit_length
实际上是log base 2向上舍入-1,并且非常快。所以,把2提高到它的幂,你就完成了。也许做
1我不确定python是如何实现位长度的,但即使是对于
x
的巨大值,它也几乎是即时的。不过,我认为这是将2取到
x-1
的第次方,然后取
位长度。其实情况正好相反。这样,中间整数会很快变大,但这样更合理。仍然不是我所说的直观。需要日志,我认为这比较慢。@jhoyla性能很少相关(缓慢的部分是查找两个函数并调用它们,而不是专门调用
log
)。这肯定更具可读性和明显性(至少对我来说)。唯一能确定它是否更慢的方法是测试…但它确实有缺点,它说
next\u-power\u-of-two(0)
是一个
DomainError
而不是1…@jhoyla:哦,说得好。每个版本都有一个简单的修复程序,但我不确定哪一个版本在修复后看起来更清晰…(另外,
next\u power\u of_two(0)也是有争议的)
应该是
0
,而不是
1
,因为
0
-inf
的第次幂,因此也是
-inf+1
的第次幂…但是无论哪种方式,
2
显然是错误的。)请注意,
x==0
的结果是不正确的,因为
(-1)。位长度()==1
在Python中。请注意准确性
math.log(2**29,2)
为29.000000000000004,因此
power\u log(2**29)
给出了错误的答案30。@ColonelPanic如果使用
math.log2
,您注意到的问题就不存在了,这是理所当然的。只有在使用
math.log
的情况下,问题才从29岁开始存在。比特旋转黑客非常棒,但请引用来源
def nextpower(num, base):
  i = 1
  while i < num: i *= base
  return i