2

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

これを回避するにはどうすればよいですか?複雑な除算のより単純なルールではなく、なぜプログラマーがこれを行ったのか

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

ありがとう

/*! @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;
}
4

3 に答える 3

1

ratio元のプログラマーは、おそらく適切な精度が維持されることを保証するために、最終的に0から1(両端を含む)になることを保証していたように私には見えます。

ウィキペディアでのアルゴリズムの単純なコーディングは、非常に大きな除数を取得する危険性があるように見えます。

また、私が知る限り、次のテスト:

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

abiとが両方ともゼロの場合にのみ真になる可能性がabrあるため、実際のゼロ除算の状況になります。

(その時点abiで、abr両方とも非負になるように強制されており、そのコードパスは次の場合にのみヒットします(abr <= abi))。

おそらく、がゼロ以外のときにゼロ除算がヒットすることを示す小さなテストケースを投稿できrます。

于 2011-01-05T02:57:36.747 に答える
0

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

于 2011-01-05T02:49:19.223 に答える
-1

誰もが初めてすべてを完璧に書いたとしたら、私たちの多くは無職になると思います。

他の人のコードを使用すると、常にこのような問題が発生するリスクがあります。そのため、Apache実装(std :: complex)のようなものを使用することをお勧めします。彼らのもののほとんどはかなりよく手入れされ、精査されています。

于 2011-01-05T02:39:04.263 に答える