未初始化double变量prob致在线判题错误的原因咨询
为何未初始化
prob变量会导致程序在在线判题系统中判错? 我编写的C语言程序输出与在线判题系统的样例完全一致,但始终被判错误。经过多次调试后,仅将声明语句double prob;修改为double prob=0.0;就修复了问题,想知道其中的缘由。
出错代码
#include <stdio.h> int main(){ double score,div,prob,coin=0.5; int n,k; scanf("%d %d",&n,&k); div= 1.0/n; for(int i=1;i<=n;i++){ score =i; coin=1; while(score<k){ score*=2; coin*=0.5; } prob= prob+(coin * div); } printf("%.12lf",prob); }
正确代码
#include <stdio.h> int main(){ double score,div,prob=0.0,coin=0.5; int n,k; scanf("%d %d",&n,&k); div= 1.0/n; for(int i=1;i<=n;i++){ score =i; coin=1; while(score<k){ score*=2; coin*=0.5; } prob= prob+(coin * div); } printf("%.12lf",prob); }
原因解析
- 自动变量的默认状态:在C语言中,函数内部声明的普通自动变量(无
static修饰)不会被自动初始化,其内存空间会保留之前程序运行遗留的随机垃圾值。prob就是这类变量,未初始化时它的值是不可预测的。 - 错误的累加计算:代码中执行
prob= prob+(coin * div);时,第一次计算会用prob的垃圾值作为初始值参与运算,后续每次累加都会带着这个错误的初始值,最终结果必然偏离正确值。 - 样例的巧合假象:你看到输出与样例一致,可能是某次运行时垃圾值恰好为0,或者该垃圾值在样例输入的计算中影响极小,被输出的精度格式(
%.12lf)掩盖了。但在线判题系统的测试用例不止公开样例,其他隐藏用例下垃圾值的影响会显现,导致判错。 - OJ的严格精度校验:在线判题系统对输出精度的校验非常严格,哪怕结果存在极小的数值偏差(比如因垃圾值导致结果多了一个极小的浮点数),都会被判定为错误。
内容的提问来源于stack exchange,提问作者stup
相关产品推荐
相关产品推荐

