我正在尝试使用下面的程序来除复数,它适用于复数,但不适用于分母为实数(即复数部分为零)的情况。被零除发生在这一行 ratio = b->r/b->i ;
中,当复数部分 b->i
为零时(在 a 的情况下实分母)。
我该如何解决这个问题?为什么程序员要这样做,而不是更直接的规则 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;
}
最佳答案
在我看来,最初的程序员正在确保 ratio
可能会在 0 和 1(含)之间结束,以确保保持足够的精度。
Wikipedia 上算法的直接编码看起来有获得一些非常大的除数的危险。
此外,据我所知,以下测试:
if (abi == 0) {
fprintf(stderr, "z_div.c: division by zero\n");
exit(-1);
}
只有当 abi
都为真时才为真和 abr
为零,因此您将处于真正被零除的情况。
(此时 abi
和 abr
都被强制为非负数,并且该代码路径仅在 (abr <= abi)
时被命中)。
也许您可以发布一个小测试用例,显示在 r
时被零除。是非零的。
关于c - 试图除以复数,除以零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4600351/