#include <stdio.h>
#include <math.h>
int main(void) {
double stotal, smean, sd, ermean, total, mean, j, k;
int n, i;
printf("enter n numbers to be entered\n");
scanf(" %d", &n);
double x[n];
for (i = 0; i < n; i++) {
printf("enter value for X\n");
scanf(" %lf", &x[i]);
}
for (i = 0; i < n; i++) {
j = x[i];
stotal = stotal + (j * j);
printf("%f\n", total);
}
for (i = 0; i < n; i++) {
k = x[i];
total = total + k;
printf("%f\n", total);
}
mean = total / n;
smean = stotal / n;
sd = sqrt(smean - pow(mean, 2));
ermean = sd / sqrt(n);
printf("sum is %lf\n", total);
printf("mean is %lf\n", mean);
printf("sum squared is %lf\n", stotal);
printf("mean squared is %lf\n", smean);
printf("standard deviation is %lf\n", sd);
printf("error in mean is %lf", ermean);
return 0;
}
输出:
sum is -1.#QNAN0
mean is -1.#QNAN0
总和和均值的输出关闭,我怀疑是我的整个功能有问题,但我不知道如何修复它。
编辑:
这次重新编辑了代码并进行了初始化,抱歉给出了一个令人困惑的声明,该代码实际上适用于一个非常大的值,我只是忘记完全初始化必要的变量。
编辑代码:
double stotal=0,smean=0,sd=0,total=0,mean=0,j,k;
答案 0 :(得分:1)
total, stotal
未初始化。
“输入一个非常大的值” --> 对于大 x[i]
,stotal
可能由于 stotal + (j * j)
而变得无穷大。然后是在 smean - pow(mean, 2)
中减去无穷大的问题。
输出是-1.#QNAN0,我不知道为什么
注意真实数学和浮点数学之间的细微差别。
考虑到 smean - pow(mean, 2)
可能由于 FP 数学的四舍五入而略微为负,即使在数学上这不是预期的。
sd = sqrt(smean - pow(mean, 2)); // What if smean < pow(mean, 2) ?
当然 sqrt(some_negative)
会导致诸如 -1.#QNAN0 之类的麻烦。
相反,要防范1:
// sd = sqrt(smean - pow(mean, 2));
double diff = smean - pow(mean, 2);
sd = diff < 0.0 ? 0.0 : sqrt(diff);
高级:可以在下面使用以应对 -0.0。 -0.0 通常适用于 sqrt(-0.0)
--> -0.0。不过,最好避免 -0.0 标准偏差。
sd = signbit(diff) ? 0.0 : sqrt(diff);
类似问题acosf() returns NaN。
提示:不要使用 "%lf"
打印,而是使用 "%lg"
(或仅使用 "%g"
)——尤其是在调试 FP 代码时。小值信息更丰富,大值噪声更少。
1 使用此代码,任何负 diff
肯定是由于累积计算和舍入效果,标准偏差确实为 0.0。这里 diff < 0.0
是合理的。
注意这种泛化这个测试,尽管 sqrt()
的扩充比通过舍入误差合理化的结果要消极得多,以避免 < 0.0
测试隐藏一些更大的缺陷。