微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 C 中的 pow() 函数在循环中是 10 的奇数指数时给出错误答案?

如何解决为什么 C 中的 pow() 函数在循环中是 10 的奇数指数时给出错误答案?

#include <stdio.h> 
#include <math.h>

int main()
{
    int loop,place_value=0,c = 5;
    for(loop = 0; loop < c; loop++)
    {
        place_value = 0;
        place_value = pow(10,loop);
        printf("%d \n",place_value);
    }
    return 0;
}

代码给出

10 
99 
1000 
9999 

为什么第 3 行和第 5 行分别是 99 和 9999 而不是 100 和 10000?

正常请求电源时,给出正确答案。

#include <stdio.h>
#include <math.h>

int main()
{
  printf ("%d",(int) pow (10,3 ));
  return 0;
}
1000

解决方法

pow 是一个难以实现的例程,并不是所有的实现都能产生好的结果。粗略地说,pow(x,y) 的核心算法从 x 的(一部分)计算对数,乘以 y,并计算乘积的指数函数。在浮点中执行此操作会引入难以控制的舍入误差。

结果是 pow(10,4) 的计算结果可能接近 10,000,但略小或略大。如果小于,则将其转换为整数会产生 9999。

当您在源代码中使用硬编码的参数时,编译器可能会在编译期间计算答案,可能使用不同的算法。例如,当 y 为 3 时,它可能会简单地将第一个参数与其自身相乘,如在 x*x*x 中,而不是使用对数指数算法。

至于为什么您测试的奇数会出现低结果,请考虑当我们将 5.45454545 乘以 10 的各种幂并四舍五入为整数时会发生什么。 5.45454545 向下舍入为 5。54.5454545 向上舍入为 55。545.454545 向下舍入为 545。向上或向下舍入是小数点以外的小数部分的结果。对于您使用 pow(10,loop) 的情况,10 的对数位可能恰好用您尝试过的几个奇数给出了这种模式。

,

pow(x,y) 函数或多或少地转换为 exp(log(x) * y),这将给出与 x ^ y 不太相同的结果。

为了解决这个问题,你可以四舍五入:

round(pow(x,y))
,

经验法则:永远不要使用带有整数的浮点函数(尤其是像 pow 或 log 这样复杂的函数)。

只需实现整数 pow

int intpow1(unsigned x)
{
    const static unsigned vals[] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,/* ... */};

    #if defined(CHECK_OVERFLOW)
    if(x >= sizeof(vals)/ sizeof(vals[0])) return -1;
    #endif

    return vals[x];
}

它会更快甚至(最快的)

def channel_exists?(channel)
  begin
    response = @slack_client.chat_scheduleMessage(channel: channel,text: '',post_at: Time.now.to_i + 100)
    @slack_client.chat_deleteScheduledMessage(channel: channel,scheduled_message_id: response.scheduled_message_id)
    return true
  rescue Slack::Web::Api::Errors::ChannelNotFound
    return false
  end
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。