我正在寻找一种Pythonic方法来计算正整数n
的二进制表示中的尾随零的数量(这将表示2
除以n
的最高幂没有余数)。
一个简单的解决方案:
def CountZeros(n):
c = 0
while (n % 2) == 0:
n /= 2
c += 1
return c
但是为了以更加Pythonic的方式做到这一点,我认为我可以利用:
bin(n)[2:]
,它提供n
bin(n)[:1:-1]
,它提供n
所以我的问题可以简化为计算字符串中尾随零的数量。
有没有单一陈述方式可以做到这一点?
我的最终目标是用于计算2
的最高幂的Pythonic方法,它将n
除以余数,因此任何方法都不是通过计算字符串中的尾随零来实现这一点。
答案 0 :(得分:9)
您可以使用- (CGAffineTransform)targetTransform
{
return CGAffineTransformIdentity;
}
:
str.rstrip
答案 1 :(得分:5)
这可能会。
def trailing_zeros(n):
s = str(n)
return len(s)-len(s.rstrip('0'))
答案 2 :(得分:1)
我不确定这是否是最快的解决方案,但它看起来对我来说最合乎逻辑:
def trailing_zeros(n):
for i in range(20):
if n % (2<<i) != 0:
return i
既然你要求单行声明,这是一个,但我不认为它非常清晰(而且它的效率比另一个更差):
max(i+1 for i in range(20) if n%(2<<i) == 0)
答案 3 :(得分:1)
避免使用bin
转换为字符串,而使用修改后的bithack,因为我们已经有一个高效的log2
实现,所以它的速度快两倍。
def ctz(v):
return (v & -v).bit_length() - 1
如果输入为0,则上面的代码返回-1。
使用C使其速度再次提高一倍:
from gmpy2 import bit_scan1 as ctz
如果输入为零,此版本将返回None。
例如,如果输入为20,则考虑无限二进制扩展:
v 000...00010100
~v 111...11101011 (not used directly, all bits opposite)
-v 111...11101100 (-v == ~v + 1; this causes all low 1 bits to overflow and carry)
v&-v 000...00000100 (has a single 1 bit, from the carry)
and
被加完后,所有前导零和一位都是相反的,但是最后一位和所有尾随零都是相同的。
然后.bit_length()
告诉我们,整数总共使用3位,因此只需减去1即可考虑零。
答案 4 :(得分:0)
如果您特别关注数字的基础二进制表示,那么绝对使用位推操作。除法和模除法是最昂贵的操作,并且与算术而不是硬件位相关。所以(未经测试的代码)
def fnzb( n):
" return position of first non-zero bit in n"
if n==0:
# edge case, there ARE no nonzero bits
return None
for po2 in range(0, 128) # or whatever larger upper limit is desired
if a & ( 1 << po2) != 0: return po2
# edge case, n too large
raise ValueError, "'impossibly' large integer argument encountered"
如果这些整数通常非常大且有很多尾随零(对于“大”的密码值),可能可能对初始化test=1
和右 - 的效率产生重大影响
po2
个位置。