2011-01-05 7 views
2

以下のプログラムでは複素数を除算しようとしていますが、複素数に対しては機能しますが、分母が実数の場合(複合部分がゼロの場合)は機能しません。複素数部分b->iがゼロ(実数分母の場合)のとき、0で除算がこの行に発生します。ratio = b->r/b->i ;複素数を除算しようとするとゼロで除​​算する

どうすればこの問題を回避できますか? complex division

ウィキペディアのルールはより良いように見えますが、ここでゼロエラーによる除算は発生しません。私は何か見落としてますか?なぜプログラマはウィキペディアの式を使用しなかったのですか?

おかげ

/*! @file dcomplex.c 
* \brief Common arithmetic for complex type 
* 
* <pre> 
* -- SuperLU routine (version 2.0) -- 
* Univ. of California Berkeley, Xerox Palo Alto Research Center, 
* and Lawrence Berkeley National Lab. 
* November 15, 1997 
* 
* This file defines common arithmetic operations for complex type. 
* </pre> 
*/ 

#include <math.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include "slu_dcomplex.h" 


/*! \brief Complex Division c = a/b */ 
void z_div(doublecomplex *c, doublecomplex *a, doublecomplex *b) 
{ 
    double ratio, den; 
    double abr, abi, cr, ci; 

    if((abr = b->r) < 0.) 
     abr = - abr; 
    if((abi = b->i) < 0.) 
     abi = - abi; 
    if(abr <= abi) { 
     if (abi == 0) { 
      fprintf(stderr, "z_div.c: division by zero\n"); 
      exit(-1); 
     } 
     ratio = b->r/b->i ; 
     den = b->i * (1 + ratio*ratio); 
     cr = (a->r*ratio + a->i)/den; 
     ci = (a->i*ratio - a->r)/den; 
    } else { 
     ratio = b->i/b->r ; 
     den = b->r * (1 + ratio*ratio); 
     cr = (a->r + a->i*ratio)/den; 
     ci = (a->i - a->r*ratio)/den; 
    } 
    c->r = cr; 
    c->i = ci; 
} 
+0

プログラマに尋ねるそれだけでなく、 'std :: complex'を使用してください。 – GManNickG

+0

@Gman。そのCプログラム。コメントの見出しであるdcomplex.cを参照してください。 OpはC++タグ – Tom

+0

を削除する必要があります。プログラマが実際に数学者ではなかったように思えます。 PS私はTomに同意します。 –

答えて

1

元のプログラマーがratioが0と1の間で終了することを保証していたように見えますが、おそらく適切な精度が維持されていることを確認してください。

ウィキペディアでアルゴリズムを直接的にコーディングすると、非常に大きな除数が得られる危険性があります。

また、私の知る限り、次のテスト:abiabrの両方がゼロなので、あなたがゼロの状況により、実際の分水嶺になる場合

if (abi == 0) { 
     fprintf(stderr, "z_div.c: division by zero\n"); 
     exit(-1); 
    } 

は唯一の真のすることができます。

(その時点でabiabrは両方とも負ではなく、コードパスは(abr <= abi)のときにのみヒットします)。

がゼロ以外の場合、ゼロ除算がヒットしていることを示す小さなテストケースを投稿することができます。

+0

実際にあなたは正しいと思います。これらは絶対値なので、abrもゼロでなければならず、したがってゼロで割った真の状態です。 MIND BLOWN !! (それを指摘してくれてありがとう、私は問題が解決したと思う) – user553619

+0

もう一度ありがとう。問題はそれ以外の場所でなければなりません。 – user553619

+0

Phew!私が最後に浮動小数点(これは一見したがっかりしている)の質問に答えることを間違えたとき、私はかなり恥ずかしいものを投稿しました。 –

-1

誰もが完全にその後、私の推測では、私たちの多くが失業になるで初めて、すべてを書いた場合。

他の人のコードを使用すると、常にこのような問題が発生する危険があります。そのため、私はApache implementation (std::complex)のようなものを使って欲しいと思っています。彼らのもののほとんどは、きちんと保管され、審査されています。

+0

'std :: complex'はC++ STLに含まれています。 Apacheのページではその使い方についてのみ説明しています。 –

+0

また、彼は純粋なC.を使用したいと思われるコンパイラがC99をサポートしている場合は、彼自身で実装するか、_Complexを使用する必要があります。 –

+0

途中で皆助けてくれてありがとう、本当に感謝しています。プログラマーがこれらのすべてのフープを持って行ったのは、ちょっと変わったことです。 – user553619

0

このライブラリを使用する必要がありますか? C99はcomplexタイプです。

+0

私はこのライブラリを使用したいと思っています。私の教授が使用したいSuperLUマトリックスソルバーパッケージの一部です。 – user553619