尝试除复数,除以零

发布于 2024-10-10 08:46:17 字数 1612 浏览 0 评论 0原文

我正在尝试下面的程序来除复数,它适用于复数,但不适用于分母为实数(即复数部分为零)的情况。当复数部分 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;
}

I'm trying the program below to divide complex numbers, it works for complex numbers but not when the denominator is real (i.e, the complex part is zero). Division by zero occurs in this line ratio = b->r / b->i ;, when the complex part b->i is zero (in the case of a real denominator).

How do I get around this? and why did the programmer do this, instead of the more straightforward rule for complex division

The wikipedia rule seems to be better, and no division by zero error would occur here. Did I miss something? Why did the programmer not use the wikipedia formula??

Thanks

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿咻 2024-10-17 08:46:17

在我看来,最初的程序员正在确保 ratio 最终在 0 和 1(含)之间,可能是为了确保保持足够的精度。

维基百科上的算法的直接编码看起来可能会有得到一些非常大的除数的危险。

另外,据我所知,以下测试:

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

仅当 abi 和 abr 都为零时才为真,因此您将处于真正被零除的情况。

(此时 abiabr 都被强制为非负数,并且该代码路径仅在 (abr <= abi)< 时被命中/代码>)。

也许您可以发布一个小测试用例,显示当 r 不为零时被零除的情况。

Looks to me like the original programmer was ensuring that ratio would end up between 0 and 1 (inclusive) probably to ensure that adequate precision was maintained.

A straight forward coding of the algorithm on Wikipedia looks like would have danger of getting some very large divisors.

Also, as far as I can tell, the following test:

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

can only be true if both abi and abr are zero, so you would be in a real divide by zero situation.

(At that point abi and abr have both been forced to be non-negative, and that code path only gets hit when (abr <= abi)).

Perhaps you can post a small test case that shows the divide-by-zero being hit when r is non-zero.

明月松间行 2024-10-17 08:46:17

你必须使用这个库吗? C99 有一个 complex 类型。

Do you have to use this library? C99 has a complex type.

笙痞 2024-10-17 08:46:17

如果每个人第一次都写得很完美,那么我猜我们很多人都会失业。

使用他人的代码总是存在遇到此类问题的风险。因此,我建议使用类似 Apache 实现 (std::complex )。他们的大部分东西都保存得很好并且经过审查。

If everyone wrote everything perfectly the first time then my guess is a lot of us would be jobless.

Using another persons code always carries the risk of running into issues like this. For that reason, I'd sugest using something like an Apache implementation (std::complex). Most of their stuff is pretty well kept and vetted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文