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

C语言统计double类型小数点后位数运行结果异常求助

问题根源

你遇到的问题本质是二进制浮点数的精度局限性:double类型采用IEEE754标准存储,无法精确表示绝大多数十进制小数(比如你用的10.123,实际存储的是接近10.123的近似值,不是完全相等的),随着你每次乘10的操作误差不断累积,就会出现你观察到的异常现象:

  • 本该是3.0的数实际存储为2.999999999999999,modf取整数部分就得到2而不是3
  • 本该是0的小数部分实际存储为非常接近1的数值,导致判断f!=0永远成立,最后循环了50次才因为精度耗尽停止
原代码的现存问题
  • 局部变量f没有初始化就直接作为while循环的判断条件,属于未定义行为,运行结果不可预测
  • 直接用f!=0判断浮点数是否为0是错误做法,浮点数计算存在天然误差,几乎不会出现严格等于0的情况
  • 没有考虑误差累积的影响,每次乘10的操作会放大之前的精度误差,导致整数部分取值错误
修正后的代码
#include <math.h>
#include <stdio.h>       

int main()
{
  double integer_part;
  double fractional_part;
  int count = 0;
  double num = 10.123;
  // 精度阈值,小于这个值就认为小数部分为0,可根据实际需求调整精度
  const double eps = 1e-9;

  // 先拆分一次再进入循环,避免变量未初始化问题
  fractional_part = modf(num, &integer_part);
  
  while(fractional_part > eps){
    count = count + 1;
    num = fractional_part * 10;
    fractional_part = modf(num, &integer_part);
    // 可选:打开注释打印过程方便调试
    // printf("第%d位:整数部分%lf,剩余小数部分%lf\n", count, integer_part, fractional_part);
  }
  printf("Count = %d", count);

  return 0;
}
额外建议

如果你的需求是精确统计十进制数字的小数位数,完全避免浮点数精度问题,更推荐的做法是直接将输入作为字符串读取,找到小数点的位置后统计小数点之后的字符个数即可,这种方法完全不会有精度误差。


内容的提问来源于stack exchange,提问作者Anastay Kaiser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:54:02