免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 21281 | 回复: 14
打印 上一主题 下一主题

浮点数除法:25.8除以3为什么不等于8.6? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-29 10:10 |只看该作者 |倒序浏览
#include <stdio.h>
#include <stdlib.h>

main()
{
        float   sum=25.8;
        float   num=3;

        float   grade=0;

        grade=sum/num;
        printf("sum=%lf,num=%lf,grade=%lf\n", sum, num, grade);
        exit(0);
}

先是发现:25.8除以3不等于8.6。

用上面的测试程序运行后从输出:

sum=25.799999,num=3.000000,grade=8.599999

发现原来不是除法的问题,而是被除数就不对……

为什么25.8变成了25.799999?

把sum的类型改为double就可以了,但是我怕sum的值再变为某个数,又会出现上面的问题……

[ 本帖最后由 celavi 于 2008-7-29 11:22 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-29 10:14 |只看该作者
原帖由 celavi 于 2008-7-29 10:10 发表
#include
#include

main()
{
        float   sum=25.8;
        float   num=3;

        float   grade=0;

        grade=sum/num;
        printf("sum=%lf,num=%lf,grade=%lf\n", sum, num, ...

你的程序已经隐含了精确到小数后一位的含义. 因此25.6和25.7999999是一样的. 如果你需要精确, 那么你的除数和被除数应该改为25.8000000和3.00000000

论坛徽章:
0
3 [报告]
发表于 2008-07-29 10:17 |只看该作者
float 型的数貌似需要这样定义的

float sum = 25.8f;
你那样定义默认是double型的,编译的时候可能会有警告。

还有打印的时候对应关系是:
float ------>f
double---->lf

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
4 [报告]
发表于 2008-07-29 10:51 |只看该作者
一些10进制的有限小数表示成二进制可能是无限循环的。

比如,十进制的0.8意为 8 × 1/10;而二进制的0.111表示 1 * 1/2 + 1 * 1/2^2 + 1 * 1/2^3 = 0.5 + 0.25 + 0.125 = 0.875

显然,0.8的二进制表示是一个无限循环小数。

论坛徽章:
0
5 [报告]
发表于 2008-07-29 11:03 |只看该作者
谢谢二位的回答

我刚才查了一下:

scanf() 用 %lf 代表双精度数, 用 %f 代表浮点数。
printf 的 %f 标识符的确既可以输出浮点数又可以输出双精度数。printf() 的确接受 %Lf, 用于输出长双精度数。

http://c-faq-chn.sourceforge.net/ccfaq/node204.html#q:12.13
http://c-faq-chn.sourceforge.net/ccfaq/node198.html

我将程序改成
#include <stdio.h>
#include <stdlib.h>

main()
{
        float   sum=25.8f;
        float   num=3.0f;

        float   grade=0.0f;

        printf("sum=%f,num=%f,grade=%f\n", sum, num, grade);
        grade=sum/num;
        printf("sum=%f,num=%f,grade=%f\n", sum, num, grade);
        exit(0);
}

输出依然是:sum=25.799999,num=3.000000,grade=8.599999

grade存在数据库里也是8.599999。

论坛徽章:
0
6 [报告]
发表于 2008-07-29 11:10 |只看该作者
原帖由 shan_ghost 于 2008-7-29 10:51 发表
一些10进制的有限小数表示成二进制可能是无限循环的。

比如,十进制的0.8意为 8 × 1/10;而二进制的0.111表示 1 * 1/2 + 1 * 1/2^2 + 1 * 1/2^3 = 0.5 + 0.25 + 0.125 = 0.875

显然,0.8的二进制表示是一 ...


谢谢,这个答案正是我想要的。

[ 本帖最后由 celavi 于 2008-7-29 11:19 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-07-29 11:12 |只看该作者
浮点数是不准确的。
能不能定一个很小的范围,只要在这个范围内就表示相等了。

论坛徽章:
0
8 [报告]
发表于 2008-07-29 11:15 |只看该作者
那就在放到数据库之前就取3位小数吧,这样应该可以。谢谢各位!

论坛徽章:
0
9 [报告]
发表于 2008-07-29 11:22 |只看该作者
二楼和三楼的是正解

论坛徽章:
0
10 [报告]
发表于 2008-07-29 11:29 |只看该作者
理解真是透彻,学习了。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP