| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6394 人关注过本帖, 1 人收藏
标题:有时用float比double更精确
只看楼主 加入收藏
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
结帖率:100%
收藏(1)
已结贴  问题点数:20 回复次数:10 
有时用float比double更精确
前段时间在论坛上有位朋友用double类型写了一个工资分解成钞票数量的程序,我简化了一下,如下:
#include <stdio.h>
int main(void)
 {
     double sum;
     int num;
     double money[6]={100,50,10,5,0.5,0.1};
     printf("请输入实发工资总额\n");
     scanf("%lf",&sum);
     for (int i=0;i<=5;i++)
     {
         num=(int)(sum/money[i]);
         if(num>0)
         printf("%f元%d张\n",money[i],num);
         sum=sum-num*money[i];
     }
 }
输入2364.6
输出为:
100.000000元23张
50.000000元1张
10.000000元1张
0.500000元9张

而我将sum和money类型改为float后,程序如下:
#include <stdio.h>
int main(void)
 {
     float sum;
     int num;
     float money[6]={100,50,10,5,0.5,0.1};
     printf("请输入实发工资总额\n");
     scanf("%f",&sum);
     for (int i=0;i<=5;i++)
     {
         num=(int)(sum/money[i]);
         if(num>0)
         printf("%f元%d张\n",money[i],num);
         sum=sum-num*money[i];
     }
 }
输入:2364.6
输出为:
100.000000元23张
50.000000元1张
10.000000元1张
0.500000元9张
0.100000元1张
反而用float类型能输出完整。
用printf打印发现,用double类型时最后一次的num=0,而此时sum和money[i]都为0.10000,也就是说此时(int)(0.10000/0.10000)==0。
而用float类型则无此现象。在这个方面似乎float类型比double类型更精确。
也许大神有更好的解释。
搜索更多相关主题的帖子: include double money 朋友 
2016-10-02 12:00
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9026
专家分:54030
注 册:2011-1-18
收藏
得分:20 
首先用double和float都是不对的,应该用整形,单位为“角”
其次经过一系列和实数不一致的运算后,float恰巧和实数结果一致,不说明float精度高。
我举个例子,有个精确1厘米的物体,你用直尺量,结果是10毫米
而用游标卡尺量,可能量出来是9.98毫米
这是因为前者的精度只到1毫米,而后者是0.02毫米,而恰巧实际的物体是10.000000毫米
直尺的测量结果是 10毫米正负1毫米,卡尺的测量结果是 9.98毫米正负0.02毫米,所以虽然直尺的测量结果和实际相同,也是直尺精度差
2016-10-02 14:03
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
#include <stdio.h>
#include <math.h>

int main()
{
    int a;
    float b;
    double c;
    double k=2;

    a=pow(5,2);
    b=pow(5,2);
    c=pow(5,2);
    printf("a=%d,b=%g,c=%g\n",a,b,c);
   
    a=pow(5,k);
    b=pow(5,k);
    c=pow(5,k);
    printf("a=%d,b=%g,c=%g\n",a,b,c);
    return 0;   
}

给楼主一段代码,去运行看看为什么结果会是这样。
2016-10-02 17:19
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
回复 3楼 linlulu001
没区别呀,结果都一样25.
2016-10-02 18:19
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
回复 2楼 rjsp
刚才我试了下,若定义sum为float型,输入3564.6,用%.15f格式打印输出为3564.600097656250000比原值大但不够精确。
而如果定义sum为double型,输入3564.6,用%.15f格式打印输出为3564.599999999999900比原值小但更精确。
这就解释了为什么用单浮点数定义能得到正确结果,而双精度型反而不行。
如果输入sum后加个0.0000000001,也能得到理想的结果,而且每项精度都比float型高得多。
谢谢你的提点。
2016-10-02 19:24
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
回复 5楼 ehszt
不同编译器确实得出的结果会不同,这点是我疏忽了。
#include <stdio.h>
int main(void)
 {
     double sum;
     double num;
     double money[6]={100,50,10,5,0.5,0.1};
     printf("请输入实发工资总额\n");
     scanf("%lf",&sum);
     for (int i=0;i<=5;i++)
     {
         num=sum/money[i];
         if(sum<1&&num-(int)num>9e-10) num+=1;
         if(num>1e-10)
         printf("%g元%d张\n",money[i],(int)num);
                  
         sum=sum-(int)num*money[i];

     }
 }

之所以用float能得出结果而double不能,关键还是double的精度高于float。
在处理float类型的数据是按照double的类型来处理,也就是说,要先将float类型的数据先转换成double类型的数据,以你输入的2364.6的小数0.6来举例。
0.6转换成二制小数0.1001 1001 1001 1001……无限循环。float的尾数部分是23bit,而double尾数部分是52bit。
那么当float类型的2364.6强制转换double类型后,数据变大。
所以在最后0.1/0.1的时候,double类型的数据实际上是0.0999999……/0.1,分母无限接近0.1,所以用int类型截取的时候就是整数0,而float类型在0.1/0.1的时候,实际上分母比0.1大,所以用int类型截取数据的时候就有整数1。
当然,并不是所有的float类型强制转换double类型都会变大。

这样写可能也不能理解,最好的办法就是你自己去找下关于float类型和double类型在内存中是如何存储。
2016-10-02 21:51
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
回复 6楼 linlulu001
谢谢你,我在scanf("%f",&sum);
后面加了句printf("%.15f\n",sum);
然后在循环里加了句printf("%.15f %.15f\n",sum,money[i]);
如果sum和money数组都定义为double型,则显示如下图:
图片附件: 游客没有浏览图片的权限,请 登录注册

如果sum和money数组都定义为float型,则结果如下:
图片附件: 游客没有浏览图片的权限,请 登录注册

我想这两张图能很好的说明问题了。
再次谢谢你的回复!
2016-10-02 22:10
hc1650070770
Rank: 2
等 级:论坛游民
帖 子:4
专家分:10
注 册:2013-9-4
收藏
得分:0 
回复 7楼 ehszt
double型的输入使用了%lf,打印时为什么没有使用呢?
2016-10-02 22:24
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
输出不用%lf好像也不会出错,但输入非加不可,不然结果都是零。
2016-10-02 22:33
hc1650070770
Rank: 2
等 级:论坛游民
帖 子:4
专家分:10
注 册:2013-9-4
收藏
得分:0 
回复 9楼 ehszt
倒也是吧!
2016-10-03 09:47
快速回复:有时用float比double更精确
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018588 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved