函数返回-nan

时间:2017-03-29 06:18:49

标签: c++ nan

我有这个代码。为什么在主程序中返回值时会产生-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;
}

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

3 个答案:

答案 0 :(得分:7)

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

根据powf的规范:

  

pow(base,exponent)返回NaN并在基数为有限且负且指数为有限且非整数的情况下引发FE_INVALID。

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

如果您尝试对立方根进行钙化,建议您改用cbrt

答案 1 :(得分:1)

cplusplus参考说:

  

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

     

库实现可以使用该参数来区分   具体实现方式中的不同NaN值。

答案 2 :(得分:1)

正如其他人所提到的,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