2017-06-28 9 views
1

私のプログラムで、方程式の根を見つけるために再配置方法を実行しているバグがありました。数学的に同じときに2つの異なる答え..?

私は、Pythonが角括弧に基づいて2つの異なる答えを生成していることに気付きました。 は、例えば

-4**(1/3) = -1.5874010519681994 
-4.0**(1/3) = -1.5874010519681994 
(-4)**(1/3) = (0.7937005259840999+1.3747296369986024j) 
(-4.0)**(1/3) = (0.7937005259840999+1.3747296369986024j) 

について私は変数xに-4.0を割り当てた、次にyにX **(1/3)を割り当て、しかし、私は、複素数の代わりに、実際の答えを得ます。

これはなぜですか?これを防ぐ簡単な方法はありますか?

おかげ

答えて

3

あなたの例には2つのことがあります。

まず、-4の角括弧は、操作の順序で否定の前に累乗が行われるので重要です。あなたの最初の2つの例では、最初に力が行われ、次に力の結果が負になります。これはあなたが期待したものなので、これをクエリしませんでしたが、これは-4の立方根を取っていませんでしたが、立方根の負の値は4でした。

第2の問題は、Pythonでの浮動小数点演算のほとんどが正確ではないことです。 1/3の結果は端数ではなく浮動小数点数です。あなたはそれがため3の上に、実際に1ではないことを示す

(6004799503160661, 18014398509481984) 

結果を得る1/3の値を格納する変数にas_integer_ratioメソッドを使用する場合は、1/3のパワーに何かを取ることは撮影と同じではありませんそのような部分が実際には関与していないので、キューブのルートです。 Pythonは指数を有理値ではなく実数値として解釈し、負の数値の場合はx**yの値は数学の場合と同様にexp(y*ln(x))と解釈されます。負の実数の対数は複素数なので、最終的な結果も複素数です。

キューブルート-4を実際に使用する場合は、最初の2つの例のように計算するだけです。あなたは、一般的には、おそらく、負の数の根を取りたい場合は、この関数は負のも、ルート(例えば)以来、多くの例をチェックする必要があります定義

def power_frac(base, numerator, denominator): 
    """Return base**(numerator/denominator) where base is a 
    floating-point number and both numerator and denominator are 
    integers. 
    """ 

で、ルーチンを書くことができます数字は本物ではありません。しかし、これを行うことができます。私はそのような関数がPythonに組み込まれているとは思わない。指数は2つの整数(または分数の値)として与えられなければならないことを覚えておいてください。指数を浮動小数点数として計算するとき、Pythonが正確な分数を計算できないからです。

あなただけの任意の実数の立方根をしたい場合は、

def cuberoot(x): 
    return x**(1/3) if x >= 0 else -(-x)**(1/3) 
+0

ありがとう、これは私自身の答えよりも詳細な説明です! – tzaman

+0

これは '1/3'の合理性とは関係ありません。パワー関数 'x ** y'は、実数値コンテキストにおいて正の' x'に対して、あるいは複素数コンテキストにおいて与えられた式を用いてすべての 'x'に対してのみ定義されます。複雑なキューブルートは最小の角度を持つルートとして定義され、数値結果は '1/3'と' 0.3333 ... 334'の違いに影響されません。 – LutzL

+0

実数値の累乗は、このようにして定義されることが多い: 'x **(m/n)'は 'x'実数と' m'と 'n'整数と' n' 'x ** m'の値が存在する場合は、その実数に複数のそのような根が存在する場合は、正の根を選択します。質問と私の答えは、この共通の定義に基づいています。あなたの定義も存在しますが、非有理数の指数に使用されます。指数は、その引数の型に依存する実際の操作のうちの1つです。私の定義がしばしば使われることを否定しますか? –

2

これはバグではありません、それは演算子の優先順位の問題です。 the docsをチェックすると、マイナス演算子-がべき乗演算子**より低い優先順位を持つことがわかります。

- (4 ** (1/3)) 

2つ目は、次のとおりです:したがって、あなたの最初の式がある

(-4) ** (1/3) 

全く同じものではありませんです。

+0

オーケーを使用することができ、が、x = -4.0場合どのように私はこれを回避するだろうと、私はX **(1/3を行います) –

+0

(-4)**(1/3)は最初の等式と同じでなければならない、計算機は –

+0

@SylentNyte:あなたの電卓(TI-Nspire CXなど)はほぼ確実に1/3を計算する合理的な種類または何かのように。実際にすべてのコンピュータ言語のように、Pythonは '1/3'を浮動小数点数として計算しますが、これは同じものではありません(私の答えを見てください)。 –

関連する問題