与C中的sqrt()函数混淆

时间:2011-03-14 10:41:12

标签: c linux

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

...

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);
        }
    }

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

5 个答案:

答案 0 :(得分:8)

你的第二个循环再次运行:500000不是一个完美的正方形,因此i < sqrt(500000)i <= sqrt(500000)始终相等,+1确保另一次迭代。

答案 1 :(得分:3)

sqrt()将返回一个浮点数,因此所有比较都是针对浮点数进行的,并且它们在设计上是不精确的,因此这两个比较高于can yield different results,因此在一个案例中你是'我会有一个一个未定义的行为。

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

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

但是,就像其他人已经说过的那样,你不应该使用浮点值(sqrt的结果)进行整数比较,因为浮点值是......棘手的。我不确定在这种情况下int是否会被转换为float,反之亦然,但无论哪种方式都不正确。

答案 4 :(得分:-2)

你试过这个吗?

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

你的浮动pont变量吗?