【问题标题】:Different results on using sqrt() and pow() functions使用 sqrt() 和 pow() 函数的不同结果
【发布时间】:2013-06-02 10:07:38
【问题描述】:

我正在解决欧拉问题。 10 要求找到所有低于 200 万的素数之和。 我在使用 sqrtpow 函数时得到了不同的结果。 使用sqrt 给出正确答案,加上使用 pow 函数需要更多时间。这是我的代码。

for(sum=0,i=3;i<=2000000;i+=2)
{
    for(j=3;j<=sqrt(i);j++)
        if(i%j==0)
            break;
    if(j>sqrt(i))
        sum+=i;
}
sum+=2;
std::cout << "\nSum = " << sum;

【问题讨论】:

  • 您如何使用pow?向我们展示您的代码。
  • 那么pow()有什么问题?
  • 您的代码缺少两对花括号和一个break 语句。 powsqrt,无论哪种方式,您都会得到错误的值。
  • 另外你什么也没问,你的每个程序给出什么结果?

标签: c++ c


【解决方案1】:

我无法在我的计算机上重现您的问题,但是您在double 上的测试是非常危险的。如果i 是素数的平方,则您依靠sqrtpow 的高精度来获得正确的结果。也许在您的系统上,一个或多个这样的正方形有轻微的舍入差异。你最好测试一下j*j &lt;= ij*j &gt; i

【讨论】:

  • 哇!这比使用 sqrt() 快 8 倍,而且它也给出了正确的答案。
  • 这并不完全正确。他对sqrt 的使用很好;当给定平方浮点数时,它将返回精确的结果。
  • @tmyklebu 我相信你是对的,sqrt 应该给出足够精确的结果。我仍然不鼓励人们依赖 double 类型的平等,除非他们真的知道自己在做什么。
  • @BryanOlivier:我不会。知道你可以用浮点做什么,它什么时候起作用,以及如何去做是非常重要的。你不是天生就理解这些东西的;你需要通过经验来学习它。 Project Euler 是一种使用工具获得低风险体验的好方法。
【解决方案2】:

首先,sqrt(x)应该pow(x,0.5)更快更准确,为什么你认为它在库中?其次,您可能会得到错误的答案,因为您的循环终止条件正在测试一个浮点数。在这 200 万个循环中的某个地方的一个小舍入可能足以甩掉总数。最后,您在循环的每次迭代中计算浮点 sqrt() 两次,这非常慢。

代替

for (j = 0; j <= sqrt(i); ++j)  . . .

试试

limit = (int)(sqrt(i) + 0.5);
for (j = 0; j <= limit; ++j) . . .

【讨论】:

  • 非常感谢先生,您的回答对我的概念有很大帮助:)
【解决方案3】:

pow 很难正确实现 --- 也就是说,像 pow(x*x, 0.5) 这样的事情会为那些 x 返回 x,这是正确的答案。很少有实现(CRlibm 是一个明显的例外)正确实现 pow

另一方面,sqrt 保证被 IEEE 规范正确舍入,这就是为什么您的代码适用于 sqrt 而不是 pow

【讨论】:

  • 很抱歉,您的回答太专业,我无法理解。
  • @sh94:浮点数基本上是二进制“科学记数法”中的数字,具有一定的精度。 (还有其他一些变幻莫测,但我会忽略它们。)基本上,我想说的是,依靠sqrt 做正确的事情是可以的,但依靠pow 是不行的做正确的事。
猜你喜欢
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
相关资源
最近更新 更多