You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两均值t检验C语言代码输出inf值的问题排查求助

两样本t检验C代码输出inf问题排查与修复

问题描述

编写了用于检验两均值差异的t检验C语言代码,运行后t值输出为inf,已初始化所有变量但无法定位问题。使用的样本数据:

  • 样本1(容量6):63、65、68、69、71、72
  • 样本2(容量10):61、62、65、66、69、69、70、71、72、73

原始代码

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

float mean(float x[], int size)
{
  float sum = 0.0;
  for (int i=0; i<size;i++)
    sum += x[i];
  return sum/size;
}

float sumsq(float x[], int size)
{
  float sum = 0.0;
  for (int i=0; i<size;i++)
    sum += pow(x[i]-mean(x,size),2);
  return sum;
}

int main(void) 
{
  int n,m; // sample sizes
  float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0,tcal;
  printf("Enter the sample sizes of the first and second samples\n");
  scanf("%d %d",&n,&m);
  float a[n],b[m];
  printf("Enter the values of 1st sample\n");
  for(int i=0;i<n;i++)
    scanf("%f", &a[i]);
  printf("Enter the values of 2nd sample\n");
  for(int i=0;i<m;i++)
    scanf("%f", &b[i]);
  
  x = mean(a,n);
  y = mean(b,m);
  s1 = sumsq(a, n);
  s2 = sumsq(b, m);
  S  = sqrt((s1+s2)/(n+m-2));
  t = (x-y)/(S*sqrt(1/n+1/m));

  printf("Enter the value of t for ur desired level of significance for %d degrees of freedom\n", m+n-2);
  scanf("%f", &tcal);

  printf("%f\n", x);
  printf("%f\n", y);
  printf("%f\n", s1);
  printf("%f\n", s2);
  printf("%f\n", S);
  printf("%f\n", t);

  if (t < tcal)
    printf("There is not enough evidence to reject null hypothesis, so, both means can be considered equal\n");
  else
    printf("Both means have a siginificant difference\n");
  
  return 0;
}

问题根源

  1. 整数除法导致分母为0:计算sqrt(1/n+1/m)时,n和m是整数类型,1/n和1/m会触发整数除法,结果均为0,最终1/n+1/m=0,开平方后仍为0。此时t = (x-y)/(S*0),当S不为0时,结果就会是inf。
  2. sumsq函数效率低下:每次循环都重复调用mean函数,时间复杂度为O(n²),虽不直接导致inf,但严重影响性能。
  3. pow函数精度与效率问题:使用pow计算平方,不如直接用乘法(x[i]-mu)*(x[i]-mu)高效且精度更稳定。

修复后的代码

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

// 计算均值
float mean(float x[], int size)
{
  float sum = 0.0;
  for (int i = 0; i < size; i++)
    sum += x[i];
  return sum / size;
}

// 计算离均差平方和:先算一次均值,避免重复计算
float sumsq(float x[], int size)
{
  float mu = mean(x, size);
  float sum = 0.0;
  for (int i = 0; i < size; i++)
  {
    float diff = x[i] - mu;
    sum += diff * diff; // 替换pow,提升效率和精度
  }
  return sum;
}

int main(void) 
{
  int n, m;
  float x_mean = 0.0, y_mean = 0.0, s1 = 0.0, s2 = 0.0, S = 0.0, t = 0.0, tcal;
  
  printf("Enter the sample sizes of the first and second samples\n");
  scanf("%d %d", &n, &m);
  
  float a[n], b[m];
  
  printf("Enter the values of 1st sample\n");
  for(int i = 0; i < n; i++)
    scanf("%f", &a[i]);
  
  printf("Enter the values of 2nd sample\n");
  for(int i = 0; i < m; i++)
    scanf("%f", &b[i]);
  
  x_mean = mean(a, n);
  y_mean = mean(b, m);
  s1 = sumsq(a, n);
  s2 = sumsq(b, m);
  
  // 合并方差计算
  S = sqrt((s1 + s2) / (n + m - 2));
  // 用1.0强制浮点除法,避免整数除法为0
  t = (x_mean - y_mean) / (S * sqrt(1.0/n + 1.0/m));

  printf("Enter the critical t-value for your desired significance level (%d degrees of freedom):\n", n + m - 2);
  scanf("%f", &tcal);

  // 输出中间结果
  printf("Sample 1 mean: %.2f\n", x_mean);
  printf("Sample 2 mean: %.2f\n", y_mean);
  printf("Sum of squares (sample 1): %.2f\n", s1);
  printf("Sum of squares (sample 2): %.2f\n", s2);
  printf("Pooled standard deviation: %.2f\n", S);
  printf("Calculated t-value: %.4f\n", t);

  // 假设检验判断(双侧检验用绝对值比较更严谨)
  if (fabs(t) < tcal)
    printf("Fail to reject the null hypothesis: the means are not significantly different.\n");
  else
    printf("Reject the null hypothesis: the means are significantly different.\n");
  
  return 0;
}

修复说明

  • 把1/n改为1.0/n,1/m改为1.0/m,强制触发浮点除法,避免分母为0的情况。
  • 优化sumsq函数:先计算一次均值再循环,将时间复杂度降为O(n)。
  • 用diff*diff替换pow(diff, 2),提升计算效率与精度。
  • 补充了绝对值判断(双侧检验的常规逻辑),修正了原判断的疏漏。
  • 优化了输出格式,让结果更易读。

内容的提问来源于stack exchange,提问作者Anweshan Goswami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:45:26