<p>也许是这样的:</p>
<pre><code>def validExponent(x,e,a,b):
"""checks if x*2.0**e is an integer in range [a,b]"""
y = x*2.0**e
return a <= y <= b and y == int(y)
def allValid(xs,e,a,b):
return all(validExponent(x,e,a,b) for x in xs)
def firstValid(xs,a,b,maxE = 100):
for e in xrange(1+maxE):
if allValid(xs,e,a,b):
return e
return "None found"
#test:
xs = [x / ( 2. ** 11 ) for x in [-12,14,-5,16,28]]
print xs
print firstValid(xs,-2**15,2**15-1)
</code></pre>
<p>输出:</p>
^{pr2}$
<p>当然,您可以编写一个包装器函数,它将接受一个字符串参数,例如<code>'bs16'</code>,并自动计算<code>a</code>,<code>b</code></p>
<p><strong>编辑时:</strong></p>
<p>1)如果你有确切的浮动值,以上应该行得通。它引入了任何舍入错误,您可能希望将<code>y == int(y)</code>替换为<code>abs(y-round(y)) < 0.00001</code>(或类似的东西)。在</p>
<p>2)除非原始整数列表中的所有整数均为偶数,否则第一个有效指数将是所需的指数。如果你有1140个值,并且它们在某种意义上是随机的,那么发生这种情况的可能性非常小。在</p>
<p><strong>在进一步编辑时:</strong>如果所讨论的浮点不是由该过程生成的,但您希望找到一个允许对给定大小的整数进行(有损)压缩的最佳指数,您可以这样做(未经彻底测试):</p>
<pre><code>import math
def maxExp(x,a,b):
"""returns largest nonnegative integer exponent e with
a <= x*2**e <= b, where a, b are integers with a <= 0 and b > 0
Throws an error if no such e exists"""
if x == 0.0:
e = -1
elif x < 0.0:
e = -1 if a == 0 else math.floor(math.log(a/float(x),2))
else:
e = math.floor(math.log(b/float(x),2))
if e >= 0:
return int(e)
else:
raise ValueError()
def bestExponent(floats,a,b):
m = min(floats)
M = max(floats)
e1 = maxExp(m,a,b)
e2 = maxExp(M,a,b)
MSE = []
for e in range(1+min(e1,e2)):
MSE.append(sum((x - round(x*2.0**e)/2.0**e)**2 for x in floats)/float(len(floats)))
minMSE = min(MSE)
for e,error in enumerate(MSE):
if error == minMSE:
return e
</code></pre>
<p>要测试它:</p>
<pre><code>>>> import random
>>> xs = [random.uniform(-10,10) for i in xrange(1000)]
>>> bestExponent(xs,-2**15,2**15-1)
11
</code></pre>
<p>选择公共指数11似乎是有原因的。在</p>