调用函数提供2个不同的输出值

时间:2013-05-27 22:22:02

标签: c++ c

这让我非常困惑了几天。我对C有些新意,但我通常可以通过谷歌搜索解决问题,但这让我很难过。我问了几个人,他们一直无法帮助我。

问题在于,当我在代码(48和49)中包含我标记的行时,f1计算输出与output2不同,即使它们在数学上应该相同。但是,如果我以不同的方式调用它,那么我没有这个问题。我正在使用gcc或g ++编译ubuntu 12.04(两者都有同样的问题)。

我还将代码上传到pastebin。有关问题,请参阅第48和49行。

提前感谢您的帮助。

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

#define PARAMETER1 100
#define nx1 5
#define nx2 10
#define nx3 10
#define ny1 4
#define ny2 5
#define ny3 10
#define Nx nx1+nx2+nx3+1
#define Ny ny1+ny2+ny3+1
#define X1_LENGTH 5.0     
#define X2_LENGTH 10.0
#define X3_LENGTH 50.0
#define Y1_LENGTH 0.04
#define Y2_LENGTH 5.0
#define Y3_LENGTH 20.0

double f(int j,int i);
double g(int j,int i);
double dx(int i);
double calc_value_pos(int i);
double calc_value_neg(int i);
double **matrix;
double f1(int j,int i);
double calc_value2_pos(int i);
double calc_value2_neg(int i);
double f2(int j,int i);

int main(void){

    matrix=(double **)malloc((size_t) ((Ny+1)*(Nx+1)+1)*sizeof(double * ));
    for (int j=1; j<=(Ny+1)*(Nx+1); j++) {
        matrix[j] = (double *)malloc((size_t) ((Ny+1)*(Nx+1)+1)*        sizeof(double ));
    }

    for (int j=1; j<=Ny+1; j++){
        for (int i=1; i<=Nx+1; i++){
            matrix[j][i]=0.0;
        }
    }

    for (int i=0; i<=Nx; i++){
        for (int j=0; j<=Ny; j++){
            int k=i+(j)*(Nx+1)+1;
            matrix[k][k] = f(j,i);      /*including this line causes the problem*/
            //matrix[k][k] = f1(j,i);     /* including this line does not cause the problem*/
        }
    }
    return 1;
}

double f(int j, int i){
    double output=f1(j,i)+f2(j,i);
    return output;
}
double f1(int j, int i){
    double output;
    if (i==0 || j==0 || i==Nx || j==Ny) output=0.0;
    if (i!=0 && j!= 0 && i!= Nx && j!=Ny) {
        output = (g(j,i)*g(j,i+1))/(g(j,i)*calc_value_pos(i)+g(j,i+1)*calc_value_neg(i));
        double output2;
        output2=1.0/( (calc_value_neg(i)/g(j,i)) + (calc_value_pos(i)/g(j,i+1)));
        /*if (output2!=output2) printf("output2: %lf\n",output2);*/
        if (output != output2 && output==output) printf("(j%d,i%d) output:%lf \toutput2:%lf\n",j,i,output,output2);
    }
    if (output!=output) output=0.0;
    return output;
}

double f2(int j,int i){
    /* calculates f2 for (j,i) */
    double output;
    if (j==0 || i==0) output=0.0;
    else output = g(j,i)*g(j,i-1)/(g(j,i)*calc_value2_neg(i)+g(j,i-1)*calc_value2_pos(i));
    if (output!=output) output=0.0;
    return output;
}

double calc_value2_pos(int i){
    /* calculates calc_value2_pos for X=i */
    double output= dx(i)/2.0;
    return output;
}

double calc_value2_neg(int i){
    /* calculates calc_value2_neg for X=i */
    if (i==0) printf("Warning off grid\n");
    double output= dx(i-1)/2.0;
    return output;
}

double g(int j,int i){
    double output=PARAMETER1;
    if (j==0 || i==0) output=0.0;
    if (j>=ny1+1 && j<=ny1+ny2 && i>=1 && i<=nx1) output=0.0;
    if (output!=output) printf("calc_D(%d,%d) error: output==nan\n",j,i);
    return output;
}

double calc_value_pos(int i){
    if (i==Nx) printf("Warning east pos\n");
    double output;
    output = dx(i+1)/2.0;
    if (output!=output) printf("calc_delta_e_pos(%d) error: output==nan\n",i);
    return output;
}

double calc_value_neg(int i){
    double output=dx(i)/2.0;
    if (output!=output) printf("calc_delta_e_neg(%d) error: output==nan\n",i);
    return output;
}

double dx(int i){
    double output;
    if (i<=nx1) output=1.0*X1_LENGTH/nx1;
    if (i<=nx1+nx2 && i>=nx1+1) output=1.0*X2_LENGTH/nx2;
    if (i<=nx1+nx2+nx3 && i>=nx1+nx2+1) output=1.0*X3_LENGTH/nx3;
    if (output!=output) printf("delta_x(%d) error: output==nan\n",i);
    return output;
}

2 个答案:

答案 0 :(得分:3)

calc_value_posi == 25,您拨打dx(26)

double dx(int i){
    double output;
    if (i<=nx1) output=1.0*X1_LENGTH/nx1;
    if (i<=nx1+nx2 && i>=nx1+1) output=1.0*X2_LENGTH/nx2;
    if (i<=nx1+nx2+nx3 && i>=nx1+nx2+1) output=1.0*X3_LENGTH/nx3;
    if (output!=output) printf("delta_x(%d) error: output==nan\n",i);
    return output;
}

现在,26 > nx1 + nx2 + nx3,因此您返回一个未初始化的变量,这意味着未定义的行为。

答案 1 :(得分:0)

很难弄清楚这段代码在做什么,但是:

output = (g(j,i)*g(j,i+1)) / (g(j,i)*calc_value_pos(i)+g(j,i+1)*calc_value_neg(i));
output2= 1.0/( (calc_value_neg(i)/g(j,i)) + (calc_value_pos(i)/g(j,i+1)));

我很清楚为什么这些应该在数学上相似。 来自output2

1.0/( (calc_value_neg(i)/g(j,i)) + (calc_value_pos(i)/g(j,i+1)));

所以我们交叉乘以得到一个共同点:

1.0/ ((g(j,i+1)*(calc_value_neg(i)) + (g(j,i)*(calc_value_pos(i)))/(g(j,i)*g(j,i+1))

1.0除以分数等于该分数的倒数:

g(j,i)*g(j,i+1) / (g(j,i+1)*calc_value_neg(i) + g(j,i)*(calc_value_pos(i)) )

这与您的输出完全相同:

g(j,i)*g(j,i+1) / (g(j,i)*calc_value_pos(i) + g(j,i+1)*calc_value_neg(i) )

所以错误不在于你如何表示代码,它发生在计算本身的某个地方。我无法将整个代码块放到我的头脑中进行调试,但表面上有两件事情已经跳出来了:

    f2 中的
  1. g(j,i-1)
  2. f()f1()+f2(),为什么f()f1()相同,除非f2()肯定等于零?
  3. 您是否尝试在进行计算之前直接将1.0转换为double?我之前遇到过问题(尽管不是在C中),我写了类似于1.0的东西,它被编译器视为浮点而不是双精度,然后计算在转换之前发生加倍,我得到一个舍入错误。

    尝试将其投入:

    double one_d = 1.0;
    output2= one_d/( (calc_value_neg(i)/g(j,i)) + (calc_value_pos(i)/g(j,i+1)));
    

    只是一个百灵鸟,抱歉,我没有更好的想法。