Bug #11183
Cumulative error on Complex::I ** 100000000000000000000000000000000
Description
p Complex::I ** 100000000000000000000000000000000
が、32bit 環境だと、
ruby 2.3.0dev (2015-05-21 trunk 50502) [i386-mswin32_110] t.rb:1: warning: in a**b, b may be too big (-0.08483712490438944+1.5651333429325577e+32i)
こんな感じで、変な値が出ます。
# ubuntu 64bit だと (0.9943722416631883-0.10594264962575697i)
できれば、こっちも 1+0i にぴたっとしてるといいのでしょうが。
この問題に対する、うささんのコメント:
真面目にコードを読むと、Complex#** は引数(指数)がFixnumでない場合は複素数をいったん極座標形式に変換してからrとθの双方をそれぞれ計算し、最後にf_complex_polarを使ってComplexオブジェクトにしてるのですが、θはFloatなので当然に誤差が蓄積し、という感じです。まあ、誤差が蓄積しなかったとしても、f_complex_polarの中でせっかくθが0°・90°・180°・270°のケースを特別扱いしようとしてるのにdouble値を==で比較してるのでまったく救われそうにない、という感じではありますが。
θをn倍する計算に対して、nが整数である場合は360°は0°と同じという性質を利用して誤差を蓄積しない計算をすればだいぶマシになるとは思いますが、しかしめんどくさいっすね。
Files
Updated by usa (Usaku NAKAMURA) over 5 years ago
- File my_complex.diff my_complex.diff added
めんどくさいと言いつつ、手元には、添付のような「誤差を蓄積しない計算」を試してみたパッチがありますが(コンセプトを確認するためのもので実用ではない)、次は「45°とかは?」という話になることは明らかなのでびみょーです。
より賢い方法が求められていると思われます。