作者: 機械伯爵
日時: 2009/8/13(22:37)
 機械す(一次通ったので、二次試験勉強追い込み真っ最中)

> あるところ(^_^) に書かれていた、二次元方程式の解の公式。

 ……ウチ(時間城年代記 http://blog.livedoor.jp/kikwai/)じゃん(爆)

> Pythonならば複素数が扱えるなと入れてみたら…
> 
> >>> sol = lambda a,b,c:[(-b+k*(b*b-4*a*c)**(1/2))/(2*a) for k in (1,-1)]
> >>> sol(1,2,3)
> [(-0.9999999999999999+1.4142135623730951j), (-1-1.4142135623730951j)]
> 
> この演算で実部に違いが出てくるのはまずいような気がします。
> それに、なぜ違いが発生するのかも理解できません。

 そうなんですよねぇ。
 実は次号掲載予定の「やnPy」のおまけにも書いたのだけど、複素数/虚数
に関して、どーもおかしな挙動をするみたいです(以下、Python 3.1 for Win)

>>> (-1)**(1/2)
(6.123233995736766e-17+1j)
>>>

 一応、実用的には、けたあふれを利用して、ごまかすことは出来ます。

>>> (-1)**(1/2)+1-1
1j
>>>

 解の公式であればprint関数を使って……(タプル展開が必須ですけど)

>>> sol = lambda a,b,c:[(-b+k*(b*b-4*a*c)**(1/2))/(2*a) for k in (1,-1)]
>>> print(*sol(1,2,3))
(-1+1.41421356237j) (-1-1.41421356237j)
>>>

 多分、虚数/複素数計算のアルゴリズムが関係しているとは思うんですが、
虚数計算なんてどうやってやってるのか、私の知識では皆目検討がつかない
ので「誤差、出るんだなぁ」で納得しちゃってました。

 ちなみに、この式の本来の目的は、因数分解できる式の確認用、程度ですが、
コレがうまく働かない=解の公式を当てはめてもPythonではあまり高精度では
計算できない、ということになるんでしょうかねぇ。

 /機械伯爵/