【问题标题】:Why does this code not do cube roots of negative numbers?为什么这段代码不做负数的立方根?
【发布时间】:2020-03-05 07:58:51
【问题描述】:

我正在用 C 语言编写一个用于生成数字根的函数,我偶然发现了一个问题:它非常适用于正数和平方根的立方根,但是当我尝试生成负数的立方根时数字,它返回:-1.#IND00 我尝试研究,结果返回的数字太大,但我不明白为什么...... ('rooter'是函数,x是radicand,ind是度数。)

我也尝试输入 '0.66' 而不是 1/ind,但结果相同。

float rooter(int x, int ind)
{
    if(ind%2==0)
    {
        if (x>=0)
            return ( pow(x, 1.0/ind) );
        else
            errore=1;
        return -1;
    }
    else
    {
        return ( pow(x, (float)1.0/ind) );
    }
}

【问题讨论】:

标签: c root cube


【解决方案1】:

到目前为止,此答案比其他答案更具哲学性,并试图解决基本问题“为什么 pow 不允许带有浮点指数的负基数?”

考虑浮点数的工作原理以及有理数的幂是如何定义的。现在给定一个负数的基数,问问自己,什么有理指数才是实数?

使用通常的数学定义 (-2)^(1/2) 不是实数,但您可以找到任意接近 1/2 的值。例如 (-2)^(49999/99999) 是真实的。这意味着,如果实现试图确定什么是真实的,那么任何浮点精度错误实际上都可能将您的表达式从真实交换为虚构,反之亦然,从程序员的角度来看,这将是不稳定的。

这种定义的另一个问题是,它要求我们以最简化的形式表示有理指数,以确定表达式是否真实。这通常不是一个简单的表示来确定。请注意,(-2)^(2/4) 是虚数,即使 -2 平方的第四个根是实数。

【讨论】:

    【解决方案2】:

    pow 必须返回复数才能在没有更复杂的 API 的情况下处理负数。他们的方法快速、易于使用且易于访问。只有一个简单的规则:底数必须为零或正数^^

    另外,为什么要浮动?

    只需将代码更改为

    else
    {
        return pow(fabs(x), 1.0 / ind) * (x < 0 ? -1 : 1);
    }
    

    【讨论】:

    • 我认为您需要 fabs(x) 作为您的第一个参数。到pow。另外,sign(x) 是标准 C 吗?
    【解决方案3】:

    正如 AProgrammer 所述,pow 函数在您的情况下不接受否定的x。为了解决这个问题,您可以“记住”x 的符号,将其 值(大小)传递给 pow,然后重新应用该符号(因为您已经检查过ind 在这种情况下是奇数):

    else {
        float sign = x < 0.0 ? -1.0 : +1.0;
    //  return sign * ( pow(fabs(x), (float)1.0/ind) ); // MNC - see comments
        return sign * ( pow(fabs(x), 1.0/ind) );        // BPC - maybe?
    }
    

    请随时要求进一步澄清和/或解释。

    【讨论】:

    • @chux 在这种情况下,我使用的是MRC 哲学(最低要求更改)(对OP 的代码),而不是BPC 哲学(最佳可能代码)! ? 但是你说得很好。
    【解决方案4】:

    pow 不接受非整数指数的负底数。 (可能是因为在传统上定义的特殊情况下工作过于繁重,尤其是在预计使用对数实现时。)

    【讨论】:

      猜你喜欢
      • 2022-12-18
      • 2016-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      相关资源
      最近更新 更多