首页 > 解决方案 > 使用 pow 函数时如何避免 -nan(ind) 错误。是否可以使用具有非整数指数的负基数的 pow

问题描述

使用 pow 功能-nan(ind) 打印到屏幕时出现错误。想知道是否有一种方法可以将 pow 与具有负基数和非整数指数的数字一起使用。

目前 pow 函数是 pow(-12.4112021858, 0.2)。并给我 -nan(ind) 错误。如果我将基数更改为 12.41,它似乎计算得非常好。

编辑 - 我将指数设置为与 0.2 不同的数字

int main() {



    double a = 1.83;
    double v = 1.25;
    double r = 0;

    double sum = 0;
 
    double exponent = 0.2;

    double result = 1;
    while (true)
    {
    printf("Enter Radius \n");
    scanf_s("%lf", &r);
    sum = 1 - r/ a;
    printf("%lf\n", sum);
    sum = sum * v;
    printf("%lf\n", sum);
    sum=  pow(sum, exponent);
    printf("%lf\n", sum);

}
}

标签: cdebuggingmathpow

解决方案


想知道是否有一种方法可以将 pow 与具有负基数和非整数指数的数字一起使用。

首先,检查文档。C 2018 7.12.7.4 指定powfpowpowl

pow函数计算提高x到幂y。如果x是有限且负数,并且y是有限且不是整数值,则会发生域错误......</p>

您的x,大约为 -12.4112021858,是有限且负的,您的y,大约为 0.2,是有限的,而不是整数值。因此发生域错误。

这意味着您不能期望得到结果,除非pow您使用的专门提供对超出 C 标准要求的其他情况的支持,即使 .2 在 .2 中精确表示也是如此double

(当出现域错误时,将返回实现定义的结果。这可能是 NaN、有效的数学结果,例如 -2pow(-32, .2)表示使用基于十进制的浮点数,或其他。实现可能也通过errno或浮点异常报告错误。有关更多信息,请参阅 C 2018 7.12.1。)

其次,.2 不能以double大多数 C 实现的格式表示。C 实现通常使用 IEEE-754 binary64 格式。在这种格式中,最接近 0.2 的可表示值是 0.200000000000000011102230246251565404236316680908203125。对于源代码pow(-12.4112021858, .2),首先将数字转换为double,然后pow使用参数 -12.41120218580000056363132898695766925811767578125 和 0.200000000000000011102230246251565404236316680908203 调用 因此,您不是在请求具有实数结果的操作。

如果您的 C 实现使用基于十进制的浮点,则 .2 将是可表示的,并且pow(-12.4112021858, .2)返回 的第五个根是合理的x,因为第五个根是负实数。(这将是对标准规范的扩展,pow如上所述。)

如果您知道y应该是五分之一或有理数p / q,其中q是奇数,您可以计算所需的结果,pow(fabs(x), y)如果p是偶数,copysign(pow(fabs(x), y), x)如果p是奇数。

建议使用的评论之一cpow,但这不会产生您想要的结果。cpow(-12.4112021858, .2)将返回大约 1.3388 + .9727 i。(复幂“函数”是多值的,但cpow被定义为产生该结果。)


推荐阅读