C语言新手遇到float计算错误问题,求教

yyq785 2025-02-19 22:33:40

为什么计算结果不对,是因为float计算浮点数的问题吗,我试了如果换成把a定义为double就没有问题了

 

 

...全文
700 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
精度的问题
forever74 02-21
  • 打赏
  • 举报
回复 1

浮点数因为长度有限所以精度有限,这个是浮点数特性,不算是错误。
换成double也是精度有限的,只不过精度超出了你的输出位数,所以你没有发现。

赵4老师 02-20
  • 打赏
  • 举报
回复

仅供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
    float f;
    double d;
    char bs[65];
    char b[65];
    char s[80];
    unsigned char *p;
    char e[12];
    char *t;
    int ex;
    int flag;

    flag=0;
    while (1) {
        printf("Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:");fflush(stdout);
        rewind(stdin);
        fgets(s,80,stdin);
        if ('\n'==s[0]) return 1;
        if (1==sscanf(s,"0x%16I64X",(__int64 *)&d) && strlen(s)>11) {flag=2;break;}
        if (1==sscanf(s,"0x%8X"    ,(  int   *)&f))                 {flag=1;break;}
        if (1==sscanf(s,"%f"       ,           &f)
         && 1==sscanf(s,"%lf"      ,           &d))                 {flag=3;break;}
    }
    if (flag&1) {
        printf("f=%.6g\n",f);
        p=(unsigned char *)&f;
        printf("hex=%02X %02X %02X %02X\n",p[3],p[2],p[1],p[0]);
        ltoa(*(long *)&f,b,2);
        sprintf(bs,"%032s",b);
        printf("bin=%s\n",bs);
        printf("bin=%.1s %.8s   %s\n",bs,bs+1,bs+9);
        strncpy(e,bs+1,8);e[8]=0;
        ex=strtol(e,&t,2);
        printf("    %c %-4d-127 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
        ex-=127;
        printf("    %c %-8d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
    }
    if (flag&2) {
        printf("\nd=%.15lg\n",d);
        p=(unsigned char *)&d;
        printf("hex=%02X %02X %02X %02X %02X %02X %02X %02X\n",p[7],p[6],p[5],p[4],p[3],p[2],p[1],p[0]);
        _i64toa(*(__int64 *)&d,b,2);
        sprintf(bs,"%064s",b);
        printf("bin=%s\n",bs);
        printf("bin=%.1s %.11s   %s\n",bs,bs+1,bs+12);
        strncpy(e,bs+1,11);e[11]=0;
        ex=strtol(e,&t,2);
        printf("    %c %-6d-1023 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
        ex-=1023;
        printf("    %c %-11d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
    }

    return 0;
}
//Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0x3FC0000000000000
//
//d=0.125
//hex=3F C0 00 00 00 00 00 00
//bin=0011111111000000000000000000000000000000000000000000000000000000
//bin=0 01111111100   0000000000000000000000000000000000000000000000000000
//    + 1020  -1023 1.0000000000000000000000000000000000000000000000000000
//    + -3          1.0000000000000000000000000000000000000000000000000000
//
//Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0x3E000000
//
//f=0.125
//hex=3E 00 00 00
//bin=00111110000000000000000000000000
//bin=0 01111100   00000000000000000000000
//    + 124 -127 1.00000000000000000000000
//    + -3       1.00000000000000000000000
//
//Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0.125
//f=0.125
//hex=3E 00 00 00
//bin=00111110000000000000000000000000
//bin=0 01111100   00000000000000000000000
//    + 124 -127 1.00000000000000000000000
//    + -3       1.00000000000000000000000
//
//d=0.125
//hex=3F C0 00 00 00 00 00 00
//bin=0011111111000000000000000000000000000000000000000000000000000000
//bin=0 01111111100   0000000000000000000000000000000000000000000000000000
//    + 1020  -1023 1.0000000000000000000000000000000000000000000000000000
//    + -3          1.0000000000000000000000000000000000000000000000000000
//
//Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:
//


yyq785 02-19
  • 打赏
  • 举报
回复 1

关于你的C语言程序计算结果问题,确实是浮点数据类型精度导致的问题。以下是具体原因分析及建议:

float与double精度差异

float为32位浮点类型(约6-7位有效数字)
double为64位浮点类型(约15-17位有效数字)
将代码中的a改为double类型能消除误差的根本原因在于更高的存储精度。
具体数值分析
在float类型存储10.1时:

float a = 10.1f;
printf("%.15f\n", a); // 实际值会显示接近 10.099999428710
这会直接影响计算结果:
10.099999 * (10*10) = 1009.9999 (与精确值1010存在微小误差)

精度丢失过程

用int计算的b*b首先产生的整型结果100(无误差)
当与float型a相乘时:
100会被转换为float型(32位)完成运算
由于float的有限精度,累积误差在乘法中被放大
推荐解决方案

double a = 10.1; // 使用double类型
double c = a*(b*b);
工程实践建议

默认情况下推荐使用double而非float类型
仅在资源受限场景(如嵌入式系统)考虑使用float
注意浮点数运算中的常见问题:
√ 精度累积误差
√ 比较运算时应使用容错阈值(如fabs(a-b) < 1e-6)
你的代码经过调整后最终正确版本应为:

#include <stdio.h>
#include <stdlib.h>
int main() {
double a = 10.1; // 修改为double
int b = 10;
double c = a * (b * b);
printf("%lf*(%d*%d)=%lf\n", a, b, b, c); // 对应修改格式说明符
system("pause");
return 0;
}
如需验证float的精度限制,可以使用以下代码段:

float f = 10.1f;
double d = 10.1;
printf("float存储值: %.15f\n", f); // 输出近似值
printf("double存储值: %.15f\n", d); // 更接近真实值

70,005

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧