65,199
社区成员




#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<math.h>
#define N 103
#define N1 63
#define N2 40
void GAUSS(double a[N][N], double b[N]) //高斯消元子程序
{
int i, j, k, ida;
double da, temp, bei, sum;
for (k = 0; k<N - 1; k++) //选主元素并换行
{
da = a[k][k];
ida = k;
for (i = k + 1; i<N; i++)
{
if (fabs(a[i][k])>fabs(da))
{
da = a[i][k];
ida = i;
}
}
if (ida != k)
{
for (j = k; j<N; j++)
{
temp = a[k][j];
a[k][j] = a[ida][j];
a[ida][j] = temp;
}
temp = b[k];
b[k] = b[ida];
b[ida] = temp;
}
//转为上三角矩阵
for (i = k + 1; i<N; i++)
{
bei = a[i][k] / a[k][k];
for (j = k; j<N; j++)
a[i][j] -= bei*a[k][j];
b[i] -= bei*b[k];
}
}
b[N - 1] = b[N - 1] / a[N - 1][N - 1];
for (i = N - 2; i >= 0; i--)
{
for (j = i + 1, sum = 0; j<N; j++)
sum += a[i][j] * b[j];
b[i] = (b[i] - sum) / a[i][i];
}
}
void main() //主程序
{
int i, j, k;
double m, n, p, q, temp, a[N1] = { 0 }, x[N] = { 0 }, y[N] = { 0 },
b[N1][3] = { 0 }, c[N1][3] = { 0 },
dya[3][3] = { 0 }, aa[N][N] = { 0 }, bz[N2][2] = { 0 },
jg[N] = { 0 };
int dy[N1][3] = { 0 },tem;
FILE * fp;
printf("开始读入X,Y坐标\n");
fp = fopen("X坐标.txt", "r");
if (fp != NULL) {
for (i = 0; i < N; i++) {
fscanf(fp, "%lf", &x[i]);
}
}
else
printf("打开文件出错(X坐标.txt)\n");
fclose(fp);
printf("读入X坐标完成\n");
fp = fopen("Y坐标.txt", "r");
if (fp != NULL) {
for (i = 0; i < N; i++) {
fscanf(fp, "%lf", &y[i]);
}
}
else
printf("打开文件出错(Y坐标.txt)\n");
fclose(fp);
printf("读入Y坐标完成\n");
printf("开始读入三角形单元\n");
fp = fopen("三角形单元.txt", "r");
if (fp != NULL) {
for (i = 0; i < N1; i++) {
fscanf(fp, "%d %d %d", &dy[i][0], &dy[i][1], &dy[i][2]);
}
}
else
printf("打开文件出错(三角形单元.txt)\n");
fclose(fp);
printf("读入三角形单元完成\n");
printf("开始读入边界节点值\n");
fp = fopen("边界节点.txt", "r");
if (fp != NULL) {
for (i = 0; i < N2; i++) {
fscanf(fp, "%lf %lf", &bz[i][0], &bz[i][1]);
}
}
else
printf("打开文件出错(边界节点.txt)\n");
fclose(fp);
printf("读入边界节点值完成\n");
//求解单个单元三角形面积
for (i = 0; i < N1; i++)
{
m = x[dy[i][1] - 1] - x[dy[i][0] - 1];
n = y[dy[i][2] - 1] - y[dy[i][0] - 1];
p = y[dy[i][1] - 1] - y[dy[i][0] - 1];
q = x[dy[i][2] - 1] - x[dy[i][0] - 1];
a[i] = fabs(0.5*(m*n - p*q));
}
//求各单元b、c值//
for (i = 0; i < N1; i++)
{
b[i][0] = (y[dy[i][1] - 1] - y[dy[i][2] - 1]) / (2 * a[i]);
b[i][1] = (y[dy[i][2] - 1] - y[dy[i][0] - 1]) / (2 * a[i]);
b[i][2] = (y[dy[i][0] - 1] - y[dy[i][1] - 1]) / (2 * a[i]);
c[i][0] = (x[dy[i][2] - 1] - x[dy[i][1] - 1]) / (2 * a[i]);
c[i][1] = (x[dy[i][0] - 1] - x[dy[i][2] - 1]) / (2 * a[i]);
c[i][2] = (x[dy[i][1] - 1] - x[dy[i][0] - 1]) / (2 * a[i]);
}
//求小矩阵和大矩阵总纲//
for (k = 0; k < N1; k++)
{
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
dya[i][j] = a[k] * (b[k][i] * b[k][j] + c[k][i] * c[k][j]);
// printf("%f ",dya[i][j]);
aa[dy[k][i] - 1][dy[k][j] - 1] += dya[i][j];
}
}
}
//本质边界点//
for (i = 0; i < N2; i++)
{
tem = (int)bz[i][0];
aa[tem - 1][tem - 1] = aa[tem - 1][tem - 1] * 10000000000;
jg[tem - 1] = aa[tem - 1][tem - 1] * bz[i][1];
}
GAUSS(aa, jg);
//输出结果jg[]
printf("求解结果为:\n");
fp=fopen("result.txt","w");
for(i=0;i<N;i++){
printf("ψ%d=%f\n",i+1,jg[i]);
fprintf(fp,"ψ%d=%f\n",i+1,jg[i]);
}
fclose(fp);
}
程序运行后求解的数据都出现了-nan(ind)这个问题,在下新手,请各位大佬帮忙指出这个程序哪里出了问题,谢谢!
Not A Number
估计除以0了,自己设断点看看把
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=vs-2019
// https://docs.microsoft.com/zh-cn/cpp/porting/visual-cpp-change-history-2003-2015?view=vs-2019
//
// Starting in Visual Studio 2015, if the argument that corresponds to a floating-point conversion specifier (a, A, e, E, f, F, g, G) is infinite,
// indefinite, or NaN, the formatted output conforms to the C99 standard. This table lists the formatted output:
// Value Output
// -------------- ---------
// infinity inf
// Quiet NaN nan
// Signaling NaN nan(snan)
// Indefinite NaN nan(ind)
// Any of these values may be prefixed by a sign. If a floating-point type conversion specifier character is a capital letter,
// then the output is also formatted in capital letters. For example, if the format specifier is %F instead of %f, an infinity
// is formatted as INF instead of inf. The scanf functions can also parse these strings, so these values can make a round trip
// through printf and scanf functions.
//
// Before Visual Studio 2015, the CRT used a different, non-standard format for output of infinite, indefinite, and NaN values:
// Value Output
// ------------------------------ -------------------------
// + infinity 1.#INF random-digits
// - infinity -1.#INF random-digits
// Indefinite (same as quiet NaN) digit .#IND random-digits
// NaN digit .#NAN random-digits
// Any of these may have been prefixed by a sign, and may have been formatted slightly differently depending on field width and precision,
// sometimes with unusual effects. For example, printf("%.2f\n", INFINITY) would print 1.#J because the #INF would be "rounded" to 2 digits of precision.
#include <stdio.h>
#include <float.h>
int main() {
int r;
double d1=-1.0,d2=-2.0;
printf("input two double (d1 d2):");
r=scanf("%lf%lf",&d1,&d2);
printf("scanf return:%d d1:%lg d2:%lg\n",r,d1,d2);
printf("_finite(d1):%d\n",_finite(d1));
printf("_fpclass(d1):0x%04X\n",_fpclass(d1));
return 0;
}
// input two double (d1 d2):nan 22
// scanf return:2 d1:nan d2:22
// _finite(d1):0
// _fpclass(d1):0x0002
//
// input two double (d1 d2):nan(snan) 22
// scanf return:2 d1:nan(snan) d2:22
// _finite(d1):0
// _fpclass(d1):0x0002
//
// input two double (d1 d2):nan(ind) 22
// scanf return:2 d1:-nan(ind) d2:22
// _finite(d1):0
// _fpclass(d1):0x0002
//
// input two double (d1 d2):-inf 22
// scanf return:2 d1:-inf d2:22
// _finite(d1):0
// _fpclass(d1):0x0004