调用函数给出2个不同的输出值
calling functions gives 2 different values of output
这让我困惑了好几天。我对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: %lfn",output2);*/
if (output != output2 && output==output) printf("(j%d,i%d) output:%lf toutput2:%lfn",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 gridn");
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==nann",j,i);
return output;
}
double calc_value_pos(int i){
if (i==Nx) printf("Warning east posn");
double output;
output = dx(i+1)/2.0;
if (output!=output) printf("calc_delta_e_pos(%d) error: output==nann",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==nann",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==nann",i);
return output;
}
在calc_value_pos
中,对于i == 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==nann",i);
return output;
}
现在,26 > nx1 + nx2 + nx3
,因此您返回一个未初始化的变量,这意味着未定义的行为。
很难弄清楚这段代码在做什么,但是:
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)));
我很清楚为什么这些应该在数学上相似。from 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) )
所以错误不在于你如何表示代码,它发生在计算本身的某个地方。我不能把这整个代码块放进我的脑袋里调试,但有两件事跳出来了:
-
g(j,i-1)
in f2 -
f()
是f1()+f2()
,那么为什么f()
与f1()
相同,除非f2()
绝对等于零?
在进行计算之前,您是否尝试过直接将1.0转换为双精度类型?我以前遇到过问题(尽管不是在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)));
只是开玩笑,对不起,我没有更好的主意。
相关文章:
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- C++多个输入和输出
- 如何在 main 函数中输出两个新字符串C++?
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 当对字符变量使用toupper()时,所述char变量输出多个字符.我该如何防止这种情况发生
- 如何让变量随机输出四个单词之一
- CPP - strlen 不会输出多个单词的整个长度 [仅限 C 字符串]
- 长度为 20 的 Cout'ing 数组输出 23 个字符
- 如何在C 中输出两个字符串版本,一个具有逃生字符,另一个则不是
- C++ 字符输入仅输出第一个字母
- C++:如何一次输出两个字母的字符串
- C++ - 使用 IO 重定向输入和输出多个整数
- 如何随机输出两个字符串中的一个
- 按升序输出两个时间值
- 如何高效输出两个交替字符或无需循环
- 从1函数返回并输出2个整数
- 使std::cout在同一行中一个接一个地输出多个字符串
- 输出8192个字符后停止输出
- 在c++中对齐(格式化)输出//多个变量在一行中
- 如何在c++中使用pthread或诅咒同时向屏幕输出多个字符串