python对数运算符_使用位运算[n的底2中的对数]求n=2**x的指数

简短的回答

就python而言:查找2**x的指数的最快方法是在散列为2幂的字典中查找(参见代码中的“散列查找”)

最快的按位方法是名为“展开的按位”的方法。

以前的两种方法都有定义良好(但可扩展)的上限。没有硬编码上限的最快方法是“log e”。

初步说明下面的所有速度测量都是通过timeit.Timer.repeat(testn, cycles)获得的,其中testn被设置为3,并且cycles被脚本自动调整以获得秒范围内的时间(注意:此自动调整机制中存在一个错误,该错误已在2010年2月18日修复)。

并非所有方法都可以缩放,这就是为什么我没有测试2的各种幂的所有函数

我未能使某些建议的方法工作(函数返回错误的结果)。我还没有tiem来执行一个逐步调试会话:我包含了代码(注释),以防有人通过检查发现错误(或者希望自己执行调试)

结果

函数(25)**hashlookup: 0.13s 100%

lookup: 0.15s 109%

stringcount: 0.29s 220%

unrolled_bitwise: 0.36s 272%

log_e: 0.60s 450%

bitcounter: 0.64s 479%

log_2: 0.69s 515%

ilog: 0.81s 609%

bitwise: 1.10s 821%

olgn: 1.42s 1065%

函数(231)**hashlookup: 0.11s 100%

unrolled_bitwise: 0.26s 229%

log_e: 0.30s 268%

stringcount: 0.30s 270%

log_2: 0.34s 301%

ilog: 0.41s 363%

bitwise: 0.87s 778%

olgn: 1.02s 912%

bitcounter: 1.42s 1264%

函数(2128)**hashlookup: 0.01s 100%

stringcount: 0.03s 264%

log_e: 0.04s 315%

log_2: 0.04s 383%

olgn: 0.18s 1585%

bitcounter: 1.41s 12393%

函数(21024)**log_e: 0.00s 100%

log_2: 0.01s 118%

stringcount: 0.02s 354%

olgn: 0.03s 707%

bitcounter: 1.73s 37695%

代码import math, sys

def stringcount(v):

"""mac"""

return len(bin(v)) - 3

def log_2(v):

"""mac"""

return int(round(math.log(v, 2), 0)) # 2**101 generates 100.999999999

def log_e(v):

"""bp on mac"""

return int(round(math.log(v)/0.69314718055994529, 0)) # 0.69 == log(2)

def bitcounter(v):

"""John Y on mac"""

r = 0

while v > 1 :

v >>= 1

r += 1

return r

def olgn(n) :

"""outis"""

if n < 1:

return -1

low = 0

high = sys.getsizeof(n)*8 # not the best upper-bound guesstimate, but...

while True:

mid = (low+high)//2

i = n >> mid

if i == 1:

return mid

if i == 0:

high = mid-1

else:

low = mid+1

def hashlookup(v):

"""mac on brone -- limit: v < 2**131"""

# def prepareTable(max_log2=130) :

# hash_table = {}

# for p in range(1, max_log2) :

# hash_table[2**p] = p

# return hash_table

global hash_table

return hash_table[v]

def lookup(v):

"""brone -- limit: v < 2**11"""

# def prepareTable(max_log2=10) :

# log2s_table=[0]*((1<

# for i in range(max_log2+1):

# log2s_table[1<

# return tuple(log2s_table)

global log2s_table

return log2s_table[v]

def bitwise(v):

"""Mark Byers -- limit: v < 2**32"""

b = (0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000)

S = (1, 2, 4, 8, 16)

r = 0

for i in range(4, -1, -1) :

if (v & b[i]) :

v >>= S[i];

r |= S[i];

return r

def unrolled_bitwise(v):

"""x4u on Mark Byers -- limit: v < 2**33"""

r = 0;

if v > 0xffff :

v >>= 16

r = 16;

if v > 0x00ff :

v >>= 8

r += 8;

if v > 0x000f :

v >>= 4

r += 4;

if v > 0x0003 :

v >>= 2

r += 2;

return r + (v >> 1)

def ilog(v):

"""Gregory Maxwell - (Original code: B. Terriberry) -- limit: v < 2**32"""

ret = 1

m = (not not v & 0xFFFF0000) << 4;

v >>= m;

ret |= m;

m = (not not v & 0xFF00) << 3;

v >>= m;

ret |= m;

m = (not not v & 0xF0) << 2;

v >>= m;

ret |= m;

m = (not not v & 0xC) << 1;

v >>= m;

ret |= m;

ret += (not not v & 0x2);

return ret - 1;

# following table is equal to "return hashlookup.prepareTable()"

hash_table = {...} # numbers have been cut out to avoid cluttering the post

# following table is equal to "return lookup.prepareTable()" - cached for speed

log2s_table = (...) # numbers have been cut out to avoid cluttering the post

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值