首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C边值问题,射击法

C边值问题,射击法
EN

Stack Overflow用户
提问于 2021-12-11 09:09:18
回答 1查看 214关注 0票数 0

来源:https://www.ijeter.everscience.org/Manuscripts/Volume-6/Issue-4/Vol-6-issue-4-M-54.pdf

这是用打靶法求解边值问题的程序。我决定使用割线法(换句话说,牛顿法)的公式。并决定相应地更改m3搜索。

:m3=m2+(m2-M1)(b-b2))/(1.0(b2-b1);

:m3=m2-((m2-m1)/(b2-b1))*(b2-b);

我得到了这个结果:

代码语言:javascript
复制
Exact value of M =-1.305508
0.500000        -1.#IND00
1.000000        -1.#IND00
1.500000        -1.#IND00
2.000000        -1.#IND00
2.500000        -1.#IND00
3.000000        -1.#IND00

也就是说,显然M的确切值是正确的,但是第二列不想正确计数。为什么会这样?我会非常感谢你的帮助。

代码语言:javascript
复制
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
float f1(float x, float y, float z)
{
    return(z);
}
float f2(float x, float y, float z)
{
    return(x + y);
}
float shoot(float x0, float y0, float z0, float xn, float h, int p)
{
    float x, y, z, k1, k2, k3, k4, l1, l2, l3, l4, k, l, x1, y1, z1;
    x = x0;
    y = y0;
    z = z0;
    do
    {
        k1 = h * f1(x, y, z);
        l1 = h * f2(x, y, z);
        k2 = h * f1(x + h / 2.0, y + k1 / 2.0, z + l1 / 2.0);
        l2 = h * f2(x + h / 2.0, y + k1 / 2.0, z + l1 / 2.0);
        k3 = h * f1(x + h / 2.0, y + k2 / 2.0, z + l2 / 2.0);
        l3 = h * f2(x + h / 2.0, y + k2 / 2.0, z + l2 / 2.0);
        k4 = h * f1(x + h, y + k3, z + l3);
        l4 = h * f2(x + h, y + k3, z + l3);
        l = 1 / 6.0 * (l1 + 2 * l2 + 2 * l3 + l4);
        k = 1 / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4);
        y1 = y + k;
        x1 = x + h;
        z1 = z + l;
        x = x1;
        y = y1;
        z = z1;
        if (p == 1)
        {
            printf("\n%f\t%f", x, y);
        }
    } while (x < xn);
    return(y);
}
main()
{
    float x0, y0, h, xn, yn, z0, m1, m2, m3, b, b1, b2, b3, e;
    int p = 0;
    printf("\n Enter x0,y0,xn,yn,h:");
    scanf("%f%f%f%f%f", &x0, &y0, &xn, &yn, &h);
    printf("\n Enter the trial M1:");
    scanf("%f", &m1);
    b = yn;
    z0 = m1;
    b1 = shoot(x0, y0, z0, xn, h, p = 1);
    printf("\nB1 is %f", b1);
    if (fabs(b1 - b) < 0.00005)
    {
        printf("\n The value of x and respective z are:\n");
        e = shoot(x0, y0, z0, xn, h, p = 1);
        return(0);
    }
    else
    {
        printf("\nEnter the value of M2:");
        scanf("%f", &m2);
        z0 = m2;
        b2 = shoot(x0, y0, z0, xn, h, p = 1);
        printf("\nB2 is %f", b2);
    }
    if (fabs(b2 - b) < 0.00005)
    {
        printf("\n The value of x and respective z are\n");
        e = shoot(x0, y0, z0, xn, h, p = 1);
        return(0);
    }
    else
    {
        printf("\nM2=%f\tM1=%f", m2, m1);
        m3 = m2 - ((m2 - m1) / (b2 - b1)) * (b2 - b);
        if (b1 - b2 == 0)
            exit(0);
        printf("\nExact value of M =%f", m3);
        z0 = m3;
        b3 = shoot(x0, y0, z0, xn, h, p = 0);
    }
    if (fabs(b3 - b) < 0.000005)
    {
        printf("\nThere is solution :\n");
        e = shoot(x0, y0, z0, xn, h, p = 1);
        exit(0);
    }
    do
    {
        m1 = m2;
        m2 = m3;
        b1 = b2;
        b2 = b3;
        m3 = m2 - ((m2 - m1) / (b2 - b1)) * (b2 - b);
        z0 = m3;
        b3 = shoot(x0, y0, z0, xn, h, p = 0);
    } while (fabs(b3 - b) < 0.0005);
    z0 = m3;
    e = shoot(x0, y0, z0, xn, h, p = 1);
}
EN

回答 1

Stack Overflow用户

发布于 2021-12-25 10:15:11

这也是错误的文件来源,也许是一些善意的编辑看到了一个明显的错误,从来没有。

当到目标值的距离很大时,要继续的割线循环。

代码语言:javascript
复制
     do
     {
     ...
     } while (fabs(b3 - b) > 0.0005);

这样,当到目标的距离足够小时,您就离开了这个循环。这也就排除了零除法。

另外,在Runge-Kutta循环中,添加为第一行。

代码语言:javascript
复制
if(x+1.2*h>xn) h=xn-x

因此,最后一次迭代正好到达间隔结束。否则,如果xn-x0不是h的倍数,或者浮点错误以不幸的模式累积,则情况可能不是这样。这与测试数据无关,但可能发生在h=0.1中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70313881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档