2016-06-01 13 views
4

入力整数が2のべき乗かどうかを判断する簡単なプログラムを作成しようとしていました。Python数学演算の精度を扱う

私は以下のコードを持っていました。 n=5368709125368709122^29)のテストケースは失敗します。

Iはformat(y,'12g')出力0に近いが03.43965 e-07に等しくない場合、番号をフォーマットすると試みました。

この番号の問題をどのように克服する必要がありますか?

s= math.log(n,2) 
    [sh,y]=divmod(s,1) 

    if y!=0: 
    #if format(yu,'20f')!=format(0,'20f') : 
     return False 
    else: 
     return True 
+2

'math.log(536870912、2)' = '29.000000000000004' –

+2

関連するhttp://stackoverflow.com/q/588004/794749 –

+0

'math.log'は整数を返しません。浮動小数点数を返します。だからあなたのdivmodがあなたに期待された結果を与えるわけではありません。 –

答えて

3

あなたが山車を比較すると、ほとんどの浮動小数点不正確に許可する場合は、彼らが(if abs(x-y) < epsilon)互いの一定の許容距離内にある場合、あなたは通常、チェックします。

あなたが知りたい場合は、整数が2のべき乗であれば、あなたはこのようにそれを行うことができます。

def ispoweroftwo(n): 
    return (n>0 and (n&-n)==n) 

これは、符号付きの数のtwo's complement表現のルールに従って動作します。平等のための浮動小数点数を比較することについて移動する

>>> ispoweroftwo(536870911) 
False 
>>> ispoweroftwo(536870912) 
True 
2

方法はabs(a - b) < tolerancetolerance = 1e-6またはいくつかの類似した少数です。あなたの場合、それはちょうどabs(y) < 1e-6になります。

Accuracyここや人気のあるSO questionをご覧ください。

1

正確さが必要な場合は、精度ホイールを再開発したくない場合は、この種の目的のために正確に設計されたNumPyをご覧ください(多数の種類)。

import numpy as np 

x = np.array([0, 1, 2, 2**4, 536870912]) 
np.log2(x) 

# array([-Inf, 0., 1., 4., 29.]) 

np.log2()またはquickstart tutorialためdocumentation参照してください。