問題が発生する状況は 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を参照してください。
これは、数値安定性の観点からこの問題の処理を提供します。とりわけ、上記で (再) 導出した方程式は「ビエタの公式」と呼ばれることがわかります。