【问题标题】:Function returns -nan函数返回 -nan
【发布时间】:2017-03-29 16:07:57
【问题描述】:

我有这个代码。为什么在主程序返回值时会产生-nan

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace::std;

float f(float x)
{
    float result = -5 * x * x - 2 * x + 1;
    return powf(result, (float)1/(float)3);
}
int main()
{
    cout<<f(-1)<<endl;
    getchar();
    return 0;
}

这让我很困惑。据我所知,我使用合适的数据类型。

【问题讨论】:

  • -5 * x * x - 2 * x + 1-1 是负数
  • If the base is finite negative and the exponent is finite but not an integer value, it causes a domain error. 它在参考页面上说得对。
  • @slawekwin:实际上,负数确实有奇数根(例如,-27 的立方根是 -3)。只有负数的偶数根需要虚数。
  • @JerryCoffin:实际上所有的根都需要虚数:三次根有 2 个虚数和 1 个实数。
  • @AdrianMaire:确实也有复数根(就像正数的复数根一样),但是负数有纯粹的奇数根。所以不,不是所有的根需要虚数。

标签: c++ nan


【解决方案1】:

当您使用负数调用函数时,基数等于 -2,指数为 1/3(非整数)。

根据powf的规范:

pow(base, exponent) 如果 base 是有限且负数且 exponent 是有限且非整数,则返回 NaN 并引发 FE_INVALID。

这解释了为什么你的函数返回 NaN。

如果您尝试计算三次根,我建议您改用cbrt

【讨论】:

    【解决方案2】:

    正如其他人所提到的,std::pow 不提供所需的功能。相反,您可以使用 std::cbrt 或简单地这样做:

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    
    using namespace::std;
    
    float f(float x)
    {
        float result = -5 * x * x - 2 * x + 1;
        float intermediate = powf(std::abs(result),(float)1/(float)3);
        if (std::signbit(result))
            return -intermediate; // Negate if 'result' is negative
        return intermediate;
    }
    int main()
    {
        cout<<f(-1)<<endl;
        getchar();
        return 0;
    }
    

    您也可以只使用std::pow 的重载之一,而不是powf

    #include<iostream> // std::cout, std::endl
    #include<cstdio>   // getchar
    #include<cmath>    // std::pow, std::abs, std::signbit
    
    float f(float x)
    {
        float result = -5.0f * x * x - 2.0f * x + 1.0f;
        float intermediate = std::pow(std::abs(result),1.0f/3.0f);
        if (std::signbit(result))
            return -intermediate; // Negate if 'result' is negative
        return intermediate;
    }
    
    int main()
    {
        std::cout << f(-1) << std::endl;
        getchar();
    }
    

    在线here

    【讨论】:

      【解决方案3】:

      cplusplus参考说:

      NaN 值用于标识未定义或不可表示 浮点元素的值,例如 负数或 0/0 的结果。

      库实现可以使用该参数来区分 以特定于实现方式的不同 NaN 值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-06
        • 2021-05-10
        • 2012-09-08
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 2018-02-05
        相关资源
        最近更新 更多