對 n 次測量值 x₁, x₂, ..., xₙ,A類不確定度(標準不確定度)為:
u = sqrt( Σ(xᵢ - x̄)² / (n*(n-1)) ),其中 x̄ 為算術平均值。
等價於 平均值的實驗標準差:u = s / sqrt(n),s² = Σ(xᵢ - x̄)² / (n-1)。
逐個讀取數據,避免存儲所有歷史值,數值穩定性優於直接累加平方差。
// 狀態變量
int n = 0;
double mean = 0.0;
double M2 = 0.0; // 平方差累積
// 每讀入一個新值 x
n++;
double delta = x - mean;
mean += delta / n;
double delta2 = x - mean;
M2 += delta * delta2;
// 當 n >= 2 時可輸出不確定度
if (n >= 2) {
double variance = M2 / (n - 1); // 樣本方差
double std_dev = sqrt(variance); // 樣本標準差
double uncertainty = std_dev / sqrt(n); // A類不確定度
printf("n=%d, mean=%.6f, u=%.6f\n", n, mean, uncertainty);
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "用法: %s <數據文件>\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (!fp) { perror("打開文件失敗"); return 1; }
int n = 0;
double mean = 0.0, M2 = 0.0, x;
while (fscanf(fp, "%lf", &x) == 1) {
n++;
double delta = x - mean;
mean += delta / n;
double delta2 = x - mean;
M2 += delta * delta2;
if (n >= 2) {
double u = sqrt(M2 / (n - 1)) / sqrt(n);
printf("讀入第 %d 個值: %.6f 當前均值: %.6f A類不確定度: %.6f\n",
n, x, mean, u);
} else {
printf("讀入第 1 個值: %.6f 均值: %.6f (樣本數不足,無法計算不確定度)\n", x, mean);
}
}
fclose(fp);
return 0;
}
gcc -o uncertainty uncertainty.c -lm
echo -e "10.1\n10.3\n9.9\n10.2\n10.0" > data.txt
./uncertainty data.txt