-1

ax 2 + bx + c = 0 の実根を計算する Python プログラムを作成するとします。係数 a、b、c は実数で与えられます。2 つの解の伝統的な式は次のとおりです。

x1 = (-b - sqrt(b*b-4*a*c)) / 2a, 
x2 = (-b + sqrt(b*b-4*a*c)) / 2a.

数式が意味をなさない、または大きな丸め誤差につながる状況 (係数の値) を特定し、問題を回避するためにこれらの場合に使用できる代替数式を提案する必要があります。

私は何をする必要がありますか?

4

1 に答える 1

2

問題が発生する状況は 2 つあります。1 つ目は、平方根内の項 (「判別式」) が負になる場合です。つまり、

if(b*b - 4*a*c < 0 ):
  # do something. This doesn't have real roots

2番目はより微妙です。ほぼ同じサイズの 2 つの大きな数値を減算すると、丸め誤差が発生する可能性があります。これは、小さいルートの場合に発生し4*a*c << b*bます。級数展開を行うことができます:

b - sqrt(b*b - 4*a*c)
= b * ( 1 - sqrt(1 - 4 * a * c / (b * b)))
~ b * ( 1 - 1 + 2 * a * c / (b * b))        # when 4*a*c << b*b

この用語は

2 * a * c / b

したがって、最終的なルートは次のようになります

x1 = - c / b

これは興味深い結果です。もちろん、他のルートはまだです

x2 = (b + sqrt( b * b - 4 * a * c)) / (2 * a)

そこにはあまりエラーが伝播しません - あなたはそれが傾向があると言うことができますが

x2 = - b / a

c が非常に小さくなるとき。

これはすべて Python とは関係ありません。これは基本的な数学です。そして、私は間違いを犯したかもしれません - 先に進んで、それらを見つけられるかどうか見てください.

詳細については、http://en.wikipedia.org/wiki/Quadratic_equation#Floating-point_implementationを参照してください。

これは、数値安定性の観点からこの問題の処理を提供します。とりわけ、上記で (再) 導出した方程式は「ビエタの公式」と呼ばれることがわかります。

于 2013-09-17T20:09:30.773 に答える