【问题标题】:Where is the bug in my polynomial calculation code?我的多项式计算代码中的错误在哪里?
【发布时间】:2011-09-27 07:11:24
【问题描述】:

我的目标是比较计算多项式的两种不同方法。 但是如果你在 Mac 上运行它(我的电脑是 MacBook Air) 你会发现这两个结果是不同的...... 。但.... 如果您删除“/* ... */”部分或删除“for ...”之前的两个“//” 它工作正常...

plus..它在 linux 上运行良好...

谁能告诉我为什么?..

这是我的程序:

#define MAX_NUM 10
#define TEST_TIME 1
#define test_type double

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

test_type normal_method(test_type *a, test_type x, int degree)
{
    test_type s = 0.0;
    test_type e = 1.0;

    for (int i = 0; i <= degree; i++) {
        s += a[i] * e;
        e *= x;
    }

    printf("%lf\n", s);

    return s;
}

test_type horner_method(test_type *a, test_type x, int degree)
{
    test_type s = a[degree];

    for (int i = degree - 1; i >= 0; i--) {
        s *= x;
        s += a[i];
    }

    printf("%lf\n", s);

    return s;
}

void generate_data(test_type *a, test_type *x, int degree)
{
    srand( time(NULL) );
    for (int i = 0; i <= degree; i++) {
        a[i] = (test_type)(rand() % MAX_NUM + 1) / (test_type)(rand() % MAX_NUM + 1);
        *x = (test_type)(rand() % MAX_NUM + 1) / (test_type)(rand() % MAX_NUM + 1);
    }

}

int main()
{
    const int degree = 10;
    test_type a[degree];
    test_type x;

    generate_data(a, &x, degree);

//Just by clear the /**/ below, the program will work fine....
/*    
    printf("x = %lf\n", x);
    for (int i = 0; i <= degree; i++) {
        printf("%lf\n", a[i]);
    }
*/
    clock_t begin, end;

//  Or clear the two // below, it will work fine too....

    begin = clock();
//    for (int i = 0; i < TEST_TIME; i++) 
        normal_method(a, x, degree);
    end = clock();
    printf("The normal method used %d clock times\n", end - begin);

    begin = clock();
//    for (int i = 0; i < TEST_TIME; i++)
        horner_method(a, x, degree);
    end = clock();
    printf("The horner method used %d clock times\n", end - begin);

    return 0;
}

【问题讨论】:

  • 首先这不是一个惊人的问题。其次,代码前的巨大注释块说明他们的代码上下文不足。
  • 是的,这个问题最好命名为“当我删除 cmets 时程序会改变行为”。
  • 您还定义了一个容量为 10 的数组,但稍后写入它的索引 10(这是第十一个元素)。

标签: c macos gcc


【解决方案1】:

您正在访问的内存超出了您在main 中创建并在其他函数中使用的数组的范围。这至少发生在三个地方。

  • normal_method 中的循环边界从零变为十:

    for (int i = 0; i <= degree; i++) {  // a[degree] is out of bounds
    
  • 在horner_method 的第一行,您正在访问超出数组范围的内存:

    test_type s = a[degree];  // a[degree] is out of bounds
    
  • generate_data 中的循环边界不正确,与 normal_method 中的方式相同:

    for (int i = 0; i <= degree; i++) {  // a[degree] is out of bounds
    

【讨论】:

  • 还有generate_data 写入十一个元素(“i &lt;= degree”)。
  • 好收获。我将更新答案以添加它。 normal_method 中的循环边界同样不正确。
【解决方案2】:

您不应该使用%lf 来打印double。只需%f 就可以了。您可能会将其与需要 l 的 scanf 混淆。

使用编译器警告选项-Wall -Wextra -Wformat=2 gcc 应该会告诉您代码中的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多