与C中的sqrt()函数混淆

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

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

但是喜欢

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

编译后执行,出现Segmentation fault (core dumped)

for loop body是:

 for (i = 2; i <= sqrt(500000); i++) { summation[i * i] += i; for (j = i + 1; j <= 500000 / i; j++) { summation[i * j] += (i + j); } } 

两个循环之间有什么区别吗? 谢谢

你的第二个循环再次运行:500000不是一个完美的正方形,所以i < sqrt(500000)i <= sqrt(500000)总是相等的,+1保证了另一个迭代。

sqrt()将返回一个浮点数,所以所有的比较都是针对浮点数进行的,而且它们在设计上是不精确的,所以上面这两个比较可以得到不同的结果 ,因此在其中一种情况下,一个和未定义的行为。

我已经在cygwin下用gcc 4.3.4试过了你的代码。

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

我敢打赌,这个最后一个值触发循环体内某处的缓冲区溢出。

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

但是,就像其他人已经说过的,你不应该使用浮点值( sqrt结果)和整数比较,因为浮点值是非常棘手的。 我不确定在这种情况下int是否被转换为浮动,反之亦然,但不管怎样,这都不是正确的做法。

你试过这个吗?

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

你的ia浮动蓬不定吗?