与C中的sqrt()函数混淆

与C中的sqrt()函数混淆,c,linux,C,Linux,当我这样做时,它在我的代码中运行良好 ... for (i = 2; i <= sqrt(500000); i++) ... 这两个for循环之间有什么区别吗?谢谢你试过这个吗 for (i = 2; i < (sqrt(500000) + 1); i++) for(i=2;i

当我这样做时,它在我的代码中运行良好

...

for (i = 2; i <= sqrt(500000); i++)

...
这两个for循环之间有什么区别吗?谢谢你试过这个吗

for (i = 2; i < (sqrt(500000) + 1); i++)
for(i=2;i<(sqrt(500000)+1);i++)

您的i是浮点pont变量吗?

sqrt()
将返回一个浮点数,因此所有比较都是针对浮点数进行的,它们在设计上是不精确的,因此,上面的两个比较,因此在其中一种情况下,您将有一个未定义的行为。

您的第二个循环再次运行:500000不是一个完美的正方形,因此
i
i我已经在cygwin下使用GCC4.3.4尝试了您的代码

  • 在第一种情况下,我循环到707
  • 在第二种情况下,我循环到708

我打赌这最后一个值会在循环体的某个地方触发缓冲区溢出。

正如其他人已经解释的那样,
+1
会导致循环过于频繁地迭代一次。然后
summation[i*i]
summation[i*j]
访问超出
summation
分配大小的内容。解决方案是相应地增加分配的大小,或者确保条件正确(不执行
+1
),这样就不会在阵列的末端运行


但是,正如其他人已经说过的,您不应该使用带有整数比较的浮点值(
sqrt
)作为浮点值。。。棘手的我不确定在这种情况下int是否被转换为float,反之亦然,但无论以何种方式,这都不是正确的做法。

哎哟,在每次迭代中计算sqrt()。for
循环的
主体是什么?你引用的循环条件不能成为崩溃的原因。@Erik:编译器不会优化它吗?@Phimueme:如果你运气好的话,它可能会优化它。@DarkDust我已经为循环体添加了。老实说,我不明白这会有什么帮助。你认为添加paren会有什么不同,为什么?是的,这才是真正的答案。@sharptooth真正的答案是使用
i*i@Jim Balter谢谢你的提示。@Jim,计算sqrt(500000)并避免循环可能更有益。@Jim,是什么让你认为计算700左右的乘法比计算一个平方根花费更少?让我们测量一下
for(int i=2;ifor(int i=2;i*i
给出了0.83微秒。看看asm,我没有看到任何不必要的优化(好吧,对于最终版本,我了解到gcc能够在编译时计算sqrt(常量))。感谢提示,我在第二个循环中循环了708次,导致了缓冲区溢出。
for (i = 2; i <= sqrt(500000); i++) {
        summation[i * i] += i;
        for (j = i + 1; j <= 500000 / i; j++) {
            summation[i * j] += (i + j);
        }
    }
for (i = 2; i < (sqrt(500000) + 1); i++)