| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2521 人关注过本帖
标题:浮点数精度问题,怎么才能保证累加不出现误差
只看楼主 加入收藏
q472440947
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2014-7-13
收藏
得分:0 
回复 7 楼 周满悦
虽然没声明,但编译器可以识别,只是结果不对,运行出来只有2个结果
2014-07-14 00:06
q472440947
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2014-7-13
收藏
得分:0 
回复 10 楼 wssy213
等待你解决啊    我运行的结果只有28点几和42点几   其他的  比如1和70什么的为什么不输出来??
2014-07-14 00:24
wssy213
Rank: 12Rank: 12Rank: 12
来 自:湖南
等 级:贵宾
威 望:10
帖 子:967
专家分:3703
注 册:2014-6-6
收藏
得分:0 
就如9楼所说,这里的关键是就是浮点数的精度问题。
浮点数并不是百分百正确的,浮点数0.1十分接近数学上的1/10,但实际上并不精确的相等。所以在使用x=x+0.1时,由于精度原因,每次累加就会造成误差的累加,最后和71.0比较时就会造成在精度范围内并不相等,比如就有可能为71.000000001之类的(在C/C++中'=='是指在要求的精度范围内完全相等)。可以参考下面:
#include<stdio.h>
int main(viod)
{
    float i;
    for(i=0;i<=2.0;i+=0.1)
    {
        printf("%.1f\n",i);
    }
    return 0;
}
很显然,这个程序理论上可以输出0.0, 0.1, 0.2, ...... 2.0这些数,但实际上,大多数的pc只能输出0.0, 0.1, 0.2,..... 1.9,这就印证了上面的说法
谈到这里想必lz应该知道上面的程序为什么只能输出两个结果了吧。
正是由于浮点数的这种特性,所以,我们使用浮点数进行判断是否相等、比较大小、加减运算等等就要特别注意
例如在for循环中我们应多使用整型做循环的变量,整型是精确的。上面的程序可以这样改写:
for(i=10;i<=20;i++)
{
    x=i/10.0;
    printf("%.1f\n",x);
},这样就可以避免一些问题。
比较大小我们要知道具体所需要的精度,要在精度所允许的范围内判断。
加减时就要考虑到十进制小数在转化成二进制小数时,并不是所有的十进制小数都能转化为有限长度的二进制小数,所以可能得不到想要的结果
总之,使用浮点数前要详细的考虑到自己的实际需求

----------------------------------------------------------------------------------------
以上部分内容摘自《C语言的科学和艺术》、http://blog.、http://bbs.
此外,对于这部分我也了解的不是很清晰,故以上仅供参考,如有错误还请指出
ps:那两个链接可以看一下,讲得很详细,但有些部分有错误,所以还请留心


[ 本帖最后由 wssy213 于 2014-7-14 13:43 编辑 ]

坚持----------------------------------唯一的道路
shit ! ! !
2014-07-14 13:26
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我贴读书摘引的时候不去看,这会就问。
https://bbs.bccn.net/thread-433543-1-3.html

总有人说要读经典书,但读过的到底有没有意识到这样的文字解答了你经常问的问题?我说读书不看文字不如不看,有人偏爱反着教说只看代码足矣,都不知道怎么说好,话说重了伤和气,可事实上又真的害人不浅。教人如何读书、如何把书读懂、如何从书中找到解答,比给他一串代码有用得多。

经常遇到这种事,我说某人肯定没看书,他就强辩说看过了、就是没找到答案才上来问,但事实是那些问题在哪怕多浅薄的教科书中都肯定有讲,只是他从来不认真阅读文字、一头扎进代码中而已。读书不用心、不爱长文字的,都不是学习的料。

[ 本帖最后由 TonyDeng 于 2014-7-14 20:42 编辑 ]

授人以渔,不授人以鱼。
2014-07-14 20:31
wssy213
Rank: 12Rank: 12Rank: 12
来 自:湖南
等 级:贵宾
威 望:10
帖 子:967
专家分:3703
注 册:2014-6-6
收藏
得分:0 
回复 14 楼 TonyDeng
看过了,却又忘了
羞愧.......


[ 本帖最后由 wssy213 于 2014-7-14 20:50 编辑 ]

坚持----------------------------------唯一的道路
shit ! ! !
2014-07-14 20:49
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你简单地把1楼的程序改成用double试试,可能就过了。

授人以渔,不授人以鱼。
2014-07-14 21:16
wssy213
Rank: 12Rank: 12Rank: 12
来 自:湖南
等 级:贵宾
威 望:10
帖 子:967
专家分:3703
注 册:2014-6-6
收藏
得分:0 
回复 16 楼 TonyDeng
我之前就试过了 不行 可能精度偏差较大

坚持----------------------------------唯一的道路
shit ! ! !
2014-07-14 23:27
q472440947
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2014-7-13
收藏
得分:0 
回复 13 楼 wssy213
现在能确定是精度问题了  那如果要求必须用浮点数,怎么才能保证程序顺利运行呢?
2014-07-14 23:34
q472440947
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2014-7-13
收藏
得分:0 
回复 17 楼 wssy213
用double 直接就没有输出了   怎么才能使用浮点数累加  而不出现误差?
2014-07-14 23:35
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
程序代码:
#include <stdio.h>
#include <conio.h>
#include <math.h>

int main()
{
    const double limit = 71.0;
    double x, y;

    for (x = 0.0; x < limit; x += 0.1)
    {
        for (y = 0.0; y < limit; y += 0.1)
        {
            if (fabs((x + y) - limit) < 1e-5)
            {
                printf_s("%f,%f\n", x, y);
                //_getch();
            }
        }
    }

    _getch();
    return 0;
}

授人以渔,不授人以鱼。
2014-07-15 08:37
快速回复:浮点数精度问题,怎么才能保证累加不出现误差
数据加载中...
 
   



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

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