免费注册 查看新帖 |

Chinaunix

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

[C] 新人提问!求解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-28 23:30 |只看该作者 |倒序浏览
What do you think would be the output of the following program and why? (If you are about to say "f is 1.0", I would say check it out again)

#include <stdio.h>

int main()
{
        float f=0.0f;
        int i;

        for(i=0;i<10;i++)
                f = f + 0.1f;

        if(f == 1.0f)
                printf("f is 1.0 \n");
        else
                printf("f is NOT 1.0\n");

        return 0;
}

求解0.0f   0.1f  是曾样回事啊?   能不能回答一下上面的问题啊?  谢谢

论坛徽章:
7
巳蛇
日期:2014-04-10 08:54:57白羊座
日期:2014-04-22 20:06:262015年亚洲杯之沙特阿拉伯
日期:2015-02-10 14:18:532015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之吉达阿赫利
日期:2015-06-02 11:34:112015亚冠之武里南联
日期:2015-06-24 12:13:082015亚冠之阿尔纳斯尔
日期:2015-08-03 09:08:25
2 [报告]
发表于 2013-08-29 08:25 |只看该作者
回复 1# reborn_wwp
浮点数的存储是不精确的,所以永远都不要直接比较两个浮点数是否相等,你应该根据你的精度需求比较这两个数的差的绝对值小于你指定的一个很小的数(比如10E-6)就可以认为它们相等了。

   

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
3 [报告]
发表于 2013-08-29 09:12 |只看该作者
浮点数用的是二进制科学计数法,十进制的 0.1 换成二进制就是 0.00011001100110011001100110011……,也就是说浮点数无法用有限个位数来表示十进制的0.1。
float有23个位数,因此float只能用“二进制的 1.10011001100110011001101 * 2的-4次方”来表示0.1f。
“二进制的 1.10011001100110011001101 * 2的-4次方”转化为10进制的话就是 0.100000001490116119384765625

简单点儿这么想:
一个数,用A进制表示可能是个有限位小数,而用B进制表示可能却是个无限循环小数
f = f + 0.1f; 在编译器眼中其实就是 f = f + 0.100000001490116119384765625;

再简单点儿这么想:
浮点数是精确的,和实数一样。但浮点数不是实数,之间互相转化时可能发生截位。

顺便说一下:
浮点数用的是科学计数法,因此 (a+b)+c 就未必等于 a+(b+c),……等等

论坛徽章:
208
巨蟹座
日期:2013-09-02 09:16:36卯兔
日期:2013-09-02 20:53:59酉鸡
日期:2013-09-05 21:21:45戌狗
日期:2013-10-15 20:51:17寅虎
日期:2013-10-18 21:13:16白羊座
日期:2013-10-23 21:15:19午马
日期:2013-10-25 21:22:48技术图书徽章
日期:2013-11-01 09:11:32双鱼座
日期:2013-11-01 20:29:44丑牛
日期:2013-11-01 20:40:00卯兔
日期:2013-11-11 09:21:32酉鸡
日期:2013-12-04 19:56:39
4 [报告]
发表于 2013-08-29 09:14 |只看该作者
精度的问题,哥一般的做法是能不用float就不用
如果金融一类的先转整数再转回来

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
5 [报告]
发表于 2013-08-29 09:21 |只看该作者
浮点数的存储是不精确的
------ 反对

所以永远都不要直接比较两个浮点数是否相等
------ 反对

你应该根据你的精度需求比较这两个数的差的绝对值小于你指定的一个很小的数(比如10E-6)就可以认为它们相等了。
------ 这句话就很没道理了。
实数计算相等的两个式子,用浮点数来计算,差别可能是任意大,也就是你得把这个“很小的数”得设为很大,才能保证应该相等的会相等;
实数计算不相等的两个式子,用浮点数来计算,差别可能是任意小,也就是你得把这个“很小的数”得设为很小,才能保证不应该相等的不会相等。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
6 [报告]
发表于 2013-08-29 11:12 |只看该作者
浮点数不精确, 这是C语言常识!

论坛徽章:
0
7 [报告]
发表于 2013-08-29 22:04 |只看该作者
新人好像知道了一点。这哥好像以前我就遇见了,但还是遇到的情况不多,就不是好记在心上了。我刚改了下。
这样就是显示出  f is 1.0      了   谢谢大家 了:wink::wink::wink:
#include <stdio.h>
#define eps 10e-6

int main()
{
        float f=0.0f;
        int i;

        for(i=0;i<10;i++)
                f = f + 0.1f;

        if(f - 1.0f < eps)
                printf("f is 1.0 \n";
        else
                printf("f is NOT 1.0\n";

        return 0;
}

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
8 [报告]
发表于 2013-08-30 15:18 |只看该作者
reborn_wwp 发表于 2013-08-29 22:04
显示出  f is 1.0

显示出  f is 1.0,有不等于f真的是1.0
说 EPSILON 的,都是根本没理解浮点数是啥的人。

对于如下代码,你设个eps试试?
如果你eps设小了,就会认为 1.0e8f + 1.0f + 1.0f + 1.0f + ……共1.0e8f个…… != 2.0e8f
如果你eps设大了,就会认为 100.0f + 100.0f == 1.0f
你根本没法设置一个合适的eps,使得前者成立,后者不成立
  1. #include <stdio.h>
  2. #include <math.h>

  3. #define eps 10e-6
  4. //#define eps 1.1e8f

  5. int main()
  6. {
  7.     float f = 1.0e8f;
  8.     for( int i=0; i<100000000; ++i )
  9.         f += 1.0f;

  10.     if( fabs(f-2.0e8f) < eps )
  11.         printf( "1.0e8f + 1.0f + 1.0f + 1.0f + ……共1.0e8f个…… == 2.0e8f \n" );

  12.     //////////////////////

  13.     float f2 = 100.0f;
  14.     f2 *= 2;
  15.     if( fabs(f2-1.0f) < eps )
  16.         printf( "100.0f + 100.0f == 1.0f \n" );

  17.     return 0;
  18. }
复制代码

论坛徽章:
0
9 [报告]
发表于 2013-08-31 10:56 |只看该作者
回复 8# bruceteen

好象是知道了一点,我再去看看浮点数的有关知识。
    谢谢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP