-4

嘿,我正在尝试编写一个程序来执行牛顿法并找到方程 exp(-x)-(x^2)+3 的根。它的工作原理是找到根,但我也希望它在每次迭代后打印出根,但我无法让它工作,谁能指出我的错误,我认为它与我的索引有关?

太感谢了 :)

#include <stdio.h>
#include <math.h>
#include <malloc.h>

//Define Functions:
double evalf(double x)
{
        double answer=exp(-x)-(x*x)+3;
        return(answer);
}
double evalfprime(double x)
{
        double answer=-exp(-x)-2*x;
        return(answer);
}
double *newton(double initialrt,double accuracy,double *data)
{
        double root[102];
        data=root;
        int maxit = 0;
        root[0] = initialrt;
        for (int i=1;i<102;i++)
        {
                *(data+i)=*(data+i-1)-evalf(*(data+i-1))/evalfprime(*(data+i-1));
                if(fabs(*(data+i)-*(data+i-1))<accuracy)
                {
                        maxit=i;
                        break;
                }
                maxit=i;
        }

        if((maxit+1==102)&&(fabs(*(data+maxit)-*(data+maxit-1))>accuracy))
        {
                printf("\nMax iteration reached, method terminated");
        }      
        else
        {
                printf("\nMethod successful");
                printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1,*(data+maxit));
        }

        return(data);
}




int main()
{
    double root,accuracy;
    double *data=(double*)malloc(sizeof(double)*102);

    printf("NEWTONS METHOD PROGRAMME:\nEquation: f(x)=exp(-x)-x^2+3=0\nMax No iterations=100\n\nEnter initial root estimate\n>> ");
    scanf("%lf",&root);
    _flushall();
    printf("\nEnter accuracy required:\n>>");
    scanf("%lf",&accuracy);
    *data= *newton(root,accuracy,data);
    printf("Iteration        Root           Error\n ");
    printf("%d          %lf             \n", 0,*(data));
    for(int i=1;i<102;i++)
    {
        printf("%d             %5.5lf           %5.5lf\n", i,*(data+i),*(data+i)-*(data+i-1));
        if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0)
        {
            break;
        }
    }
    getchar();
    getchar();
    free(data);
    return(0);
}
4

3 回答 3

1

没有冒犯,但是您的问题对否决票非常诱人。不相关的问题标题,荒谬的编码风格(我的意思是制表)。

同样在您的newton函数中,实际上不需要存储所有中间结果,Newton-Raphson 不应使用额外的内存(即 O(1))。

只需在迭代循环内部printf添加即可。newton这是一个问题吗?

于 2012-04-04T10:39:33.170 回答
1

newton中,您将返回函数返回后不再存在的局部变量的地址。之后访问它是未定义的行为。

main你有

if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0)

data是 a double*,所以从头开始data + i处理第 i 个。double通过将偏移量乘以sizeof(double),您可以访问超出数组末尾的 if i > number_of_elements/sizeof(double),还有更多未定义的行为。

而且,感谢 JeremyP 在main您的电话中找到它newton

*data= *newton(root,accuracy,data);

它取消引用返回的指针newton(未定义的行为,但此时可能会做你想做的事)并将该值存储在data分配的第一个插槽中main。这可能会为您提供root数组的初始元素 from newton,但不会更改分配给datain的内存块中的任何其他内容main

于 2012-04-04T10:40:08.803 回答
0
void newton(double initialrt,double accuracy,double *data)
{
    double root[102];
    data=root;
    // at this moment the values in the original argument data[]
    // are no longer accessible to this function.
    int maxit = 0;
    root[0] = initialrt;
    for (int i=1; i < 102; i++)
        {
                data[i] = data[i-1] 
                 - evalf(data[i-1]) / evalfprime( data[i-1] );
                if ( fabs(data[i] - data[i-1]) < accuracy )
                {
                        maxit=i;
                        break;
                }
                maxit=i;
        }

        if ( maxit+1 == 102 && fabs(data[maxit] - data[maxit-1] ) > accuracy )
        {
                printf("\nMax iteration reached, method terminated");
        }      
        else
        {
                printf("\nMethod successful");
                printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1
                ,data[maxit);
        }
    return;
}

(这只是一种风格上的评论,因为真正的问题已经解决了)

  • 指针解引用和数组索引在 C 中是等价的。你*(data+i) = ...的等价于data[i] = ...
  • 返回值是无用的,该函数可以返回一些有用的东西(例如准确性)
  • return 不是函数。没必要return(something);只是return something;会做。
  • 你返回一个指向本地数组根的指针,当调用者看到它时,它超出了范围。
  • 空格会改变阅读体验

更新:再想一想,我认为在内部循环中,OP 的意图是:

root[i] = root[i-1] 
        - evalf(data[i-1]) / evalfprime( data[i-1] );
if ( fabs(data[i] - data[i-1]) < accuracy )
     {
     maxit=i;
     break;
     }
maxit=i;
于 2012-04-04T11:20:30.860 回答