CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

再开一贴,老大说“浮点数绝对不能用‘==’来比较”,我不太认同,大家觉得呢?

楼主Joe_Cai(超级小强)2006-06-19 12:43:08 在 C/C++ / C++ 语言 提问

如题,我用了7年C++,从来没有看到任何官方资料说“浮点数绝对不能用‘==’来比较”,请高手发表一下意见,谢谢~ 问题点数:100、回复次数:236Top

1 楼SuperLinux(天黑黑)回复于 2006-06-19 12:54:03 得分 1

^_^  
  这位大哥7年的C++   敬仰啊!  
   
  小弟写哥例子,不知道合适不合适……  
   
  Dev   C++   &   WinXp   SP2  
  ----------------------  
   
  #include   <cstdlib>  
  #include   <iostream>  
   
  using   namespace   std;  
   
  int   main(int   argc,   char   *argv[])  
  {  
          float   f   =   2.0/5.0;  
           
          if   (f   ==   0.4)  
          {  
                  cout<<"equal"<<endl;          
          }  
          else  
          {  
                  cout<<"unequal"<<endl;          
          }  
          system("PAUSE");  
          return   EXIT_SUCCESS;  
  }  
   
  Top

2 楼SuperLinux(天黑黑)回复于 2006-06-19 13:09:19 得分 1

再引用一下《高质量C/C++编程》这本书里的  
  P28,   4.3.3   浮点变量与零值比较  
   
  【规则4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较。  
  千万要留意,无论是float   还是double   类型的变量,都有精度限制。所以一定要避  
  免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。  
  假设浮点变量的名字为x,应当将  
  if   (x   ==   0.0)   //   隐含错误的比较  
  转化为  
  if   ((x>=-EPSINON)   &&   (x<=EPSINON))  
  其中EPSINON   是允许的误差(即精度)。  
   
  ---------  
  希望对LZ有帮助   ^_^Top

3 楼Joe_Cai(超级小强)回复于 2006-06-19 13:14:52 得分 0

我这样也不行吗?  
   
  float   var   =   1.0f;  
  if(var==1.0f)  
  {  
          ....  
  Top

4 楼okkk(和海)回复于 2006-06-19 13:15:16 得分 0

自己写几个测试程序就知道了Top

5 楼Joe_Cai(超级小强)回复于 2006-06-19 13:16:48 得分 0

请大家发表意见时,对“浮点数绝对不能用‘==’来比较”这个观点的对与错,作出明确的判断:true   or   false?    
  Thanks!!!!!!!!!Top

6 楼lddLinan(不再五行中)回复于 2006-06-19 13:21:21 得分 0

Safe   Comparisons  
  Different   computers   use   different   numbers   of   bits   to   store   floating-point   numbers.   Even   when   the   same   IEEE   formats   are   used   for   storing   numbers,   differences   in   calculations   can   occur   because   of   the   size   of   intermediate   registers.Top

7 楼cmoring(my study will go on)回复于 2006-06-19 13:21:39 得分 0

浮点数绝对不能用‘==’来比较  
  ==============================  
  这个观点是正确的!Top

8 楼xpdavis(咕嘟-不想孤独)回复于 2006-06-19 13:21:54 得分 1

一般来说不是绝对的Top

9 楼lexchou(龍子龍孫)(本人已死)(有事烧纸)回复于 2006-06-19 13:22:50 得分 0

因为是浮点小说,所以你无法精确表达一个小数,两个看起来一样的数字肯定会有误差,自然不会相等了。一般的做法是对两个数字相减,然后比较和误差数量级来确定是否近似相等Top

10 楼wudi_1982(向伴水学习|胃出血,住院中)回复于 2006-06-19 13:23:22 得分 0

学习。Top

11 楼pappGG(天天向上)回复于 2006-06-19 13:23:39 得分 0

浮点数完全可以用“==”来比较  
  问题是:这个比较结果是你需要的吗?  
   
   
  浮点数有效位数有15-16位(double),作数学运算得到的结果很可能是2.2250738585072014   E   –308这样的数字,一般意义上我们完全可以认为它等于"0",但是用"==0.0"返回的永远是false;  
   
  数学运算都会涉及一个精度问题,计算结果要求精确到小数后多少位,直接用"=="判断结果的话,显然不恰当  
  Top

12 楼xyq1986(综艺一哥)回复于 2006-06-19 13:25:28 得分 0

浮点数会有精度的问题!Top

13 楼ftkghost(小鹏)回复于 2006-06-19 13:25:29 得分 0

精度取舍的问题Top

14 楼SuperLinux(天黑黑)回复于 2006-06-19 13:26:02 得分 0

还有在这个地址里:  
  http://courses.nnu.edu/cs222bm/chap05n.ppt  
  盖PPT文档的第32页写到:  
  --------------------------  
  Comparing   float   Values  
  --  
  do   not   compare   float   values   for   equality,   compare   them   for   near-equality.  
  --  
      float     myNumber;  
      float       yourNumber;  
   
      cin     >>   myNumber;  
      cin   >>   yourNumber;  
   
      if     (   fabs   (myNumber   -   yourNumber)   <   0.00001   )  
  cout   <<   “They   are   close   enough!”     <<   endl;    
   
  -------------------------------------------------  
  ^_^  
  Top

15 楼Joe_Cai(超级小强)回复于 2006-06-19 13:27:25 得分 0

我再举个例子:  
   
  flaot   val   =   GetValue();//函数GetValue()的返回值只可能是30.0f,45.0f和60.0f  
  if(val   ==   30.0f)  
  {  
  Top

16 楼Joe_Cai(超级小强)回复于 2006-06-19 13:28:11 得分 0

上面的这个例子这样不行吗?Top

17 楼Joe_Cai(超级小强)回复于 2006-06-19 13:30:32 得分 0

请大家发表意见时,对“浮点数绝对不能用‘==’来比较”这个观点的对与错,作出明确的判断:true   or   false?    
  Thanks!!!!!!!!!Top

18 楼swunstar()回复于 2006-06-19 13:48:12 得分 0

mark~Top

19 楼pappGG(天天向上)回复于 2006-06-19 13:54:52 得分 0

我再举个例子:  
   
  flaot   val   =   GetValue();//函数GetValue()的返回值只可能是30.0f,45.0f和60.0f  
  if(val   ==   30.0f)  
  {  
  =============================================  
   
  如果函数GetValue()的返回值只可能是30.0f,45.0f和60.0f,那么你这样写是可以的,完全正确  
   
  不过在其他实时计算的情况下,返回值不太可能正好是“30.0f,45.0f和60.0f”这样的数据,就不能这样做了  
   
  Top

20 楼Joe_Cai(超级小强)回复于 2006-06-19 13:55:08 得分 0

我还是把问题简单化一下吧:  
   
  大家认为下面的例子有问题吗?  
   
  ------例1_BEGIN-------------------------------------  
   
  float   val   =   GetValue();//函数GetValue()的返回值只可能是27.5f,30.0f和60.0f  
  if(val   ==   27.5f)  
  {       ...     }  
  else   if(val   ==   30.0f)  
  {       ...     }  
  else   if(val   ==   60.0f)  
  {       ...     }  
   
  ------例1_END-------------------------------------  
  Top

21 楼Joe_Cai(超级小强)回复于 2006-06-19 13:56:50 得分 0

if(例1没问题)  
  {  
            “浮点数绝对不能用‘==’来比较”:   =   FALSE;  
  }  
  else  
  {  
              ......Top

22 楼wanderfox()回复于 2006-06-19 14:05:38 得分 0

float   val   =   GetValue();//函数GetValue()的返回值只可能是27.5f,30.0f和60.0f  
  if(val   ==   27.5f)  
  {   ...   }  
  else   if(val   ==   30.0f)  
  {   ...   }  
  else   if(val   ==   60.0f)  
  {   ...   }  
  关键是27.4999999999999能算是27.5么?Top

23 楼Joe_Cai(超级小强)回复于 2006-06-19 14:10:28 得分 0

函数GetValue()的返回值只可能是27.5f,30.0f和60.0f  
  float   GetValue(int   n)  
  {  
          switch(n){  
          case   1:   return   27.5f;  
          case   2:   return   30.0f;  
          case   3:   return   60.0f;  
          }  
  }Top

24 楼MSANDSUN(马甲)回复于 2006-06-19 14:25:09 得分 5

我支持楼主的观点,我从事数据采集和分析很多年了,也能经常听到此类的半吊子话,用易中天的话说就是“为之奈何?”  
   
  float   f   =   2.0/5.0;  
  if   (f   ==   0.4)  
  不知道这个事例能说明什么问题?我不是计算机,所以我不去计算2.0/5.0是多少,也不去计算2.0/5.0这个double转化为float时是多少。因为这里的2.0和5.0是浮点数,计算机中的浮点数,不是小学课堂上的实数。如果是实数,我知道它的结果是0.4,可惜它不是,连浮点数和实数的区别都不知道的人,……,还能编写程序?  
   
  第二个恶劣的观点就是浮点数是不精确的,或者说浮点数是有误差的。  
  懒得说明,浮点数是精确的,无误差的,但float的精确和无误差仅作用于float,而不作用于double、long   double、实数。double等亦如是。  
   
  第三个种,但这里没看到有人用,那就是有人会以   a*(b+c)   !=   a*b   +   a*c,或   a+b+c   !=   a+c+b   等等来说明浮点数的不精确。其实和一二理由相同,浮点数不是实数,不全部满足实数的那些定律。  
   
  //////   不要玩无聊的文字游戏   //////  
  a.   林锐:浮点数和零比较   if   ((x>=-EPSINON)   &&   (x<=EPSINON))  
  ---   这里就是文字游戏,明明要求的是“和零比较”,而答案却是“和零是否很近”  
   
  b.   如果函数GetValue()的返回值只可能是30.0f,45.0f和60.0f,那么你这样写是可以的,完全正确   不过在其他实时计算的情况下,返回值不太可能正好是“30.0f,45.0f和60.0f”这样的数据,就不能这样做了  
  ---   如果"不太可能",那么命题就已经不成立了。Top

25 楼SamuelKevin(曼陀罗)回复于 2006-06-19 14:31:02 得分 0

仔细看看浮点数的二进制表示。。。。Top

26 楼sghwqw()回复于 2006-06-19 14:31:26 得分 0

楼主说的也没有错的,但现在编译器就是这样的。浮点数存在精度问题  
  不能用“==”或“!=   ”形式,只能用“>=”或“<=”形式Top

27 楼MSANDSUN(马甲)回复于 2006-06-19 14:36:05 得分 1

补充说明:  
  浮点数是精确无误差的,这是数字计算机的根本要求之一,只要你用的是数字计算机,那么里面一切的计算都是精确的,无论是不是浮点数。  
  相同的问题还有,为什么C/C++中的随机函数rand()返回值是确定的?答案就是:这是数字计算机的根本协定之一,C/C++也遵行它。  
   
  回楼主:  
  float   val   =   GetValue();//函数GetValue()的返回值只可能是30.0f,45.0f和60.0f  
  if(val   ==   30.0f)  
  ---   按照标准而言,这是完全正确的。但实际工作中有一点要注意,那就是代码优化,部分编译器提供浮点数运算优化,但这个优化不是默认选项(违反标准规定的优化肯定不可能是默认选项),对于这个优化,编译器文档中肯定以最高规格提醒你,使用这个优化时,浮点数的运行将不再精确。  
  Top

28 楼Free_Wind22(还没想好...)回复于 2006-06-19 14:44:51 得分 0

markTop

29 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-06-19 14:48:36 得分 0

通常两个浮点数之间不要用“==”比较,这是因为有时候明明以为相等的,比较出来却不等。  
   
  float   GetValue(int   n)  
  {//实际的函数不象这个单纯  
          switch(n)  
          {  
                case   1:   return   27.5f;  
                case   2:   return   30.0f;  
                case   3:   return   20.1f*3;//比如明明计算的返回值是60.3  
          }  
          return   0;  
  }  
   
  int   main()  
  {  
          float   x=GetValue(3);  
          if(x==60.3f)       //但你这样比较将输出“!=”  
                  cout<<"=="<<endl;  
          else  
                  cout<<"!="<<endl;  
  }  
   
   
  但一个浮点数与绝对0值之间在某些情况下要用“==”比较。  
  当然,有人也觉得,即使是浮点数与绝对0值之间的比较也不要用“==”。  
   
  http://community.csdn.net/Expert/topic/4767/4767520.xml?temp=.7618219  
  Top

30 楼mythma(~a za, a za,fighting!fighting!fighting!fighting!fi)回复于 2006-06-19 14:53:56 得分 0

 
  事实胜于雄辩!Top

31 楼bruceteen(周星星)回复于 2006-06-19 14:55:16 得分 0

7年是怎么用C++的?   ^_^  
  未学C/C++的人肯定回答   能用==比较,因为他们以为浮点数就是实数,既然实数能,那么浮点数当然能;  
  初学C/C++的人部分回答   不能用==比较,因为他们知道浮点数不是实数,但可惜他们习性未改,还是以实数的运算结果来评价浮点数,所以他们以为不可以用==比较,但这也只是一小部分人才这样,并不是所有人都会犯   左边用浮点数计算,右边用实数计算   这个明显的错误;  
  用了7年C/C++的人,嘿嘿,用了三个月C/C++的人也不会问这个傻问题。Top

32 楼pappGG(天天向上)回复于 2006-06-19 14:55:34 得分 1

//////   不要玩无聊的文字游戏   //////  
  a.   林锐:浮点数和零比较   if   ((x>=-EPSINON)   &&   (x<=EPSINON))  
  ---   这里就是文字游戏,明明要求的是“和零比较”,而答案却是“和零是否很近”  
   
  b.   如果函数GetValue()的返回值只可能是30.0f,45.0f和60.0f,那么你这样写是可以的,完全正确   不过在其他实时计算的情况下,返回值不太可能正好是“30.0f,45.0f和60.0f”这样的数据,就不能这样做了  
   
   
  ========================================================================  
   
  这是文字游戏吗?  
  1   我明确地说明了LZ这样作是正确的  
  2   我补充了下LZ这样代码的在实际应用中比较少而已Top

33 楼steedhorse(晨星)回复于 2006-06-19 14:56:27 得分 30

浮点数完全可以用“==”来比较,关键是看你比较的目的。  
  如果你就是想看看两个浮点数从底层二进制表示的意义上是否绝对等同,那除了“==”,还有更好的方法吗?——当然,这种目的通常没啥实际用处。  
  而如果你只能想确定所比较的两个数是否在一定浮点数精度范围内已无法区别,那最好还是不要使用“==”比较。Top

34 楼bruceteen(周星星)回复于 2006-06-19 15:02:19 得分 0

case   3:   return   20.1f*3;//比如明明计算的返回值是60.3  
  ------   我就不知道了,20.1f*3   什么时候“明明”是60.3f了?  
  在下不才,不敢胡言乱语,只配讲真话  
  60.3f在计算机里以60.299999237060546875存储  
  20.1f*3在计算机里以60.3000030517578125存储Top

35 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-06-19 15:03:17 得分 0

再举个例子  
  float   GetValue(int   n)  
  {  
          switch(n){  
          case   1:   return   (5.22f+0.78f)*5;//假设你的30.0是经过类似的计算返回的  
          case   2:   return   45.0f;  
          case   3:   return   60.0f;  
          }  
  }  
   
  int   main()  
  {  
          float   x=GetValue(1);  
          if(x==30.0f)//这样比较也会输出“!=”,即使在调试时看到x也等于30.0000,但比较出来就是不等  
                  cout<<"=="<<endl;  
          else  
                  cout<<"!="<<endl;  
  }Top

36 楼bruceteen(周星星)回复于 2006-06-19 15:11:03 得分 0

re   steedhorse(晨星):  
  你讲得很对,但我也有一些论点,请您斧正一下:  
  如果==不能符合作者要求,那么<=EPSINON,或<EPSINON   也必然不能满足作者要求,因为在   ==   上遇到的问题,在   <=、<   上也一样存在。  
  简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近Top

37 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-06-19 15:11:34 得分 0

bruceteen(周星星)   (   )   信誉:100    
  case   3:   return   20.1f*3;//比如明明计算的返回值是60.3  
  ------   我就不知道了,20.1f*3   什么时候“明明”是60.3f了?  
  在下不才,不敢胡言乱语,只配讲真话  
  60.3f在计算机里以60.299999237060546875存储  
  20.1f*3在计算机里以60.3000030517578125存储  
   
  ===========================================  
  这位的火气不要这么大。  
  我说的“明明计算的返回值是60.3”是指我们口头计算的,我们头脑中以为的  
   
  正因为两个我们头脑中以为一样的浮点数在计算机中的表示可能不一样,才不能用“==”比较Top

38 楼bruceteen(周星星)回复于 2006-06-19 15:14:56 得分 0

re   A_B_C_ABC(黄瓜):关于“(5.22f+0.78f)*5;//假设你的30.0是经过类似的计算返回的”这个例子,我用   VC++2005   和   GCC3.4.2   编译,输出都是   ==Top

39 楼bruceteen(周星星)回复于 2006-06-19 15:21:04 得分 0

re   A_B_C_ABC(黄瓜):无聊的话我不说,既然计算机用的不是你头脑的中以为的实数,那么你头脑中怎么以为都不会对计算机运算带来影响,而且既然和你想象的实数没有关系,就不该把这个想象带入到编程中来。  
  我刚才是有点发火^_^,因为你看到的数值都是四舍五入后输出来的,比如   1.199   和   1.201   舍入到一位小数的话都是   1.2   ,但不代表   1.199   和   1.201   就相等。Top

40 楼iambic()回复于 2006-06-19 15:27:06 得分 0

不能。  
   
  偶尔的可以,最多只能作为“绝对”一词的文字反驳。你比较两个声明相等的浮点常量当然可以,你自己比较自己当然可以,有什么意义。  
  Top

41 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-06-19 15:29:57 得分 0

to   bruceteen(周星星)  
     
  但你明显没看懂我的意思。我的意思就是因为     两个我们头脑中以为相等的浮点数,在计算机中可能是不一样的,所以不要用“==”比较,好象与你的观点不矛盾啊。Top

42 楼goodboy1881(积木)(谁都别拦着我在水源升星)回复于 2006-06-19 15:32:38 得分 0

这种比较不仅在C++中被禁止,在java,php,matlab   等几乎所有的编程语言中都被禁止。Top

43 楼Joe_Cai(超级小强)回复于 2006-06-19 15:33:16 得分 0

好了,结贴了~  
   
  我们老大说我是钻牛角尖,我也承认!但是他说“你不知道浮点数的相等是怎么比较吗,你怎么能用‘==’呢,基础太差,水平问题”,老大对我的评价很伤人自尊,所以这个牛角尖我是钻定了!!!我不怕他炒我鱿鱼~  
   
  你懂的多,懂的深,你就不会认为“浮点数绝对不能用‘==’来比较”,因为你明白是怎么回事。相反,没有根据地一棒子打死,他的水平不言自明!!!  
   
  谢谢各位朋友的支持  
  Top

44 楼bruceteen(周星星)回复于 2006-06-19 15:39:25 得分 5

re   A_B_C_ABC(黄瓜):  
   
  我的意思是可以用“==”比较,而且如果“==”不可以,那么别无它法可以,<=EPSINON等等只是==的一个伪装而已。  
   
  其实我明白你的意思,但和你观点不一样,计算机中没有实数,所以永远不要把实数的运行结果放到程序中去,所以我从来不认为   20.1f*3   一定等于   60.3fTop

45 楼Joe_Cai(超级小强)回复于 2006-06-19 15:51:48 得分 0

再看看老外是怎么说的  
  http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.vc.languageTop

46 楼bruceteen(周星星)回复于 2006-06-19 16:04:34 得分 1

我帮你把文字贴出来  
   
  CAIBird   wrote:  
  >   when   can   I   use   operator   '=='   to   compare   two   float?  
   
  Whenever   you   want.  
   
  A   better   questsion   is   "Why   shouldn't   I   use   ==   to   compare   floats?".     The    
  answer   is:   rounding.   If   you're   comparing   values   that   are   the   result   of   a    
  mathematical   expression   that   "should"   be   equal,   there's   a   very   good   chance    
  that   they   won't   be.  
   
  float   x   =   1.0f;  
  float   y   =   1.0f     /   3;  
  if   (3f   *   y   ==   x)  
  {  
          //   this   code   will   likely   never   run  
  }  
   
  On   the   other   hand,   if   you've   assigned   a   value   from   one   variable   of   type    
  float   to   another   variable   of   type   float,   then   you   can   safely   compare   them    
  for   equality:  
   
  float   x   =   1.0f   /   3.0f;  
  float   y   =   x;  
  if   (x   ==   y)  
  {  
          //   this   code   will   always   run  
  }  
   
  Of   course,   this   is   an   unusual   situation   -   the   normal   recommendation   is   to    
  never   compare   floats   to   equality:   compare   for   an   acceptably   small   difference    
  in   value:  
   
  if   (fabs(x-y)   <   0.00001)  
  {  
          //   ...   this   will   reliably   execute   when   x   and   y   are   "equal"  
  }  
   
  --------------------------------  
  1.   他只讲到==使用时的注意点,事实上这些基本知识,在计算机的幼儿园学前班就应该掌握。  
  2.   VC怎么说并不重要,我从事了快5年的数值分析,参考了国内外无数的代码,很少看到(其实从来每看到)有使用VC的,所以VC的言论对此影响不大。当然,我并不是说VC不好,而是VC自VC5.0(包括VC5.0)之后就不将自己定位于数值分析,而是更侧重于逻辑分析,这和所有其他一切C/C++都不一样。Top

47 楼fadom(小车快跑)回复于 2006-06-19 16:05:15 得分 0

又一次从忘记中记住了哦Top

48 楼Joe_Cai(超级小强)回复于 2006-06-19 16:17:39 得分 0

To   bruceteen(周星星):  
   
  谢谢你帮我贴出来!  
  我只想知道是不是绝对就不能用‘==’来比较两个float,C++没这么规定吧!这是‘对’与‘错’的问题,而不是习惯“好”与“不好”的问题!!!  
   
  Of   course,   this   is   an   unusual   situation   -   the   normal   recommendation   is   to    
  never   compare   floats   to   equality:   compare   for   an   acceptably   small   difference    
  in   value:  
   
  请看他的用词“unusual   situation   ”和“normal   recommendation   ”,还有他说的是"Why   shouldn't   I   use   ==   to   compare   floats?".我英语虽然学的不好,但是“shouldn't”和“can't”还是有区别的吧?Top

49 楼bruceteen(周星星)回复于 2006-06-19 16:30:18 得分 0

To   Joe_Cai(超级小强):  
  当然能用,而且只能这样用。这里没有习惯“好”与“不好”的问题,因为除非你不用浮点数,否则只可以==,或类似的形式<、>、<=、>=,而不可能引入EPSINON,或者是M$说的“an   acceptably   small   difference”。我还是原来的意思,不要在意M$说什么,在这上面它毫无权威。Top

50 楼Jedimaster(CRH = 耻辱号)回复于 2006-06-19 17:01:25 得分 0

也可以用不过要非常小心  
   
  如果这个float很大,那么有效数字只有6位(好象是吧,不清楚了),这个时候即使+1   -1,比较原来的值依旧相等,所以说float不精确Top

51 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 17:51:46 得分 0

试一下  
   
  float   x   =   3.0f;  
   
  if   (   x   ==   3.0   )   cout   <<   "Yes"   <<   endl;  
  else   cout   <<   "No"   <<   endl;  
   
   
  就知道了Top

52 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 17:56:10 得分 0

错了,例子有点问题  
   
   
  地球人都知道0.35   *   100   =   35,可是计算机呢?  
   
   
  float   x   =   0.35f;  
  if   (   (int)(x   *   100.0f)   ==   35   )   cout   <<   "Yes"   <<   endl;  
  else   cout   <<   "No"   <<   endl;  
  Top

53 楼steedhorse(晨星)回复于 2006-06-19 18:04:41 得分 0

呵呵,其实大家心里都明白的。只是个不同的说法而已嘛。  
  奶油狗给出的程序中:  
  float   x   =   0.35f;  
  if   (   (int)(x   *   100.0f)   ==   35   )   cout   <<   "Yes"   <<   endl;  
  else   cout   <<   "No"   <<   endl;  
  不管程序运行的结果是“Yes”,还是“No”,不都同样说明“float是可以用‘==’比较”吗?  
  至于比较的结果是“Yes”,还是“No”,那是另一回事。能比较就必然有结果,但有结果不一定是结果就是“Yes”,就是这么简单啊。  
  从这个角度来说,只要能比较就行,就已经回答了楼主的问题,管他是Yes还是No呢,因为楼主并没要求这个程序必须输出“Yes”才算“能比较”,对不对?Top

54 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 18:09:38 得分 0

我也没说float不能用==,就算不可以,我们也可以重载一个,谁让C++这么强呢  
   
  最终还是要看Yes或no是否符合程序员原先的意图了Top

55 楼steedhorse(晨星)回复于 2006-06-19 18:10:18 得分 0

开始没注意,楼上有位pappGG(天天向上)网友已经说得很到位了。  
  浮点数完全可以用“==”来比较,问题只是这个结果是否是我们所需要。Top

56 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 18:11:44 得分 0

对了,事实上,我们并不对内置内型重载全局运算符。  
   
  bool   operator   =   (   const   float   &x,   const   float   &y   )  
  {  
  return   true;  
  }  
   
  是不可以的,如果这样的行为被允许的话,C++将会天下大乱。Top

57 楼steedhorse(晨星)回复于 2006-06-19 18:13:16 得分 0

不过楼主也确实太钻了。  
  一般非学术场合,说“不能”实际上想表达的意思就是“不应该”,这也很正常啊,呵呵。  
  大家生活中不都经常说类似的不严格的话么?:)Top

58 楼windindance(风舞轻扬·白首为功名)回复于 2006-06-19 18:15:25 得分 0

浮点数当然可以用==来比较,就如同楼主可以脱光衣服在大街上裸跑一样。  
   
  飘过Top

59 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 18:21:33 得分 0

 
  template<typename   _ty>  
  inline   bool   equal(   _ty   f1,   _ty   f2,   double   prec   =   1e-4   )  
  {  
  _ty   z(   f1   -   f2   );  
  return   (   z   <   prec   &&   z   >   -prec   );  
  }  
   
  template<typename   _ty>  
  inline   bool   unequal(   _ty   f1,   _ty   f2,   double   prec   =   1e-4   )  
  {  
  _ty   z(   f1   -   f2   );  
  return   (   z   >   prec   ||   z   <   -prec   );  
  }  
   
  大型系统的开发中,是这样解决问题的Top

60 楼Joe_Cai(超级小强)回复于 2006-06-19 18:25:39 得分 0

TO   steedhorse(晨星):  
   
  也不是我太钻,只是像你和pappGG(天天向上)说的一,具体问题要具体对待,怎么能一棒子打死,那样也太武断,太片面了吧!!!  
  实际上我写的程序只是对一些浮点数的读与比较,并没有涉及到运算,所以我觉得==是可以满足要求的!!!Top

61 楼steedhorse(晨星)回复于 2006-06-19 18:26:55 得分 8

哦,没说楼主你不对啊。  
  没看见还帮你说话吗。:P  
  只是想让你消消气嘛。:)Top

62 楼Joe_Cai(超级小强)回复于 2006-06-19 18:29:52 得分 0

TO   steedhorse(晨星):  
   
  我知道啊,你多虑了,哈Top

63 楼Joe_Cai(超级小强)回复于 2006-06-19 18:36:19 得分 0

TO   steedhorse(晨星):  
   
  我们在这个帖子里打过交道啊,哈哈  
  http://community.csdn.net/Expert/topic/4469/4469077.xml?temp=.2673914  
  Top

64 楼sinall()回复于 2006-06-19 18:55:26 得分 0

回复人:bruceteen(周星星)   (   三级(初级))   信誉:100   2006-06-19   15:11:00   得分:0  
  ?    
  re   steedhorse(晨星):  
  你讲得很对,但我也有一些论点,请您斧正一下:  
  如果==不能符合作者要求,那么<=EPSINON,或<EPSINON   也必然不能满足作者要求,因为在   ==   上遇到的问题,在   <=、<   上也一样存在。  
  简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近  
  ———————————————————————————————————————————  
  ×!  
  到底结论是什么???  
  也就是说,林锐《高质量C/C++编程》提到的方法,是否通用,还是仅限于VC???Top

65 楼FreeFice(庄鱼)回复于 2006-06-19 19:18:41 得分 0

To:   fireseed(奶油狗【回归Hello   World!】)  
   
  template<typename   _ty>  
  inline   bool   equal(   _ty   f1,   _ty   f2,   double   prec   =   1e-4   )  
  {  
  _ty   z(   f1   -   f2   );  
  return   (   z   <   prec   &&   z   >   -prec   );  
  }  
   
  template<typename   _ty>  
  inline   bool   unequal(   _ty   f1,   _ty   f2,   double   prec   =   1e-4   )  
  {  
  _ty   z(   f1   -   f2   );  
  return   (   z   >   prec   ||   z   <   -prec   );  
  }  
   
  大型系统的开发中,是这样解决问题的  
  -------------------  
  你从哪里得到这种用法的?这样做是不允许的。  
  浮点数可以使用==比较符,前面已经有人说过了,建议不使用的原因仅在于其值可能并不是你所期望的。而上述两个模板,仅在与利息无关的金融统计中才这样(目前国际金融统计1.0e-6,excl也采用这一标准)。更何况这个问题根本与模板无关,不然,String   s1,s2怎么套用你的模板!技术问题不要想当然回答。再说,制药、材料科学等许多领域,许多成分每kg才0.1μg,0.0001与之相差1000倍,这能作为计算标准吗?你说呢?Top

66 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 19:27:45 得分 0

谁不允许?  
   
  这是我所参与过的大型项目中的一例,只不过这是简化的写法罢了。  
   
  这种算法在游戏、地理信息、虚拟现实的系统中常常用到的,只不过你接触的所谓大型系统都是“MIS”吧,呵呵。Top

67 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 19:30:31 得分 0

不过,怀疑你的C++水平,或者你没有仔细看代码?下面这样的代码完全可以满足你的精度要求。  
   
  float   a   =   1.0f,   b   =   2.0f;  
  equal(   a,   b,   0   );Top

68 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-19 19:34:38 得分 10

做成模版是因为这个算法被用于一个数学库,里面有很多如matrix(矩阵)、polynomial(多项式)、CollisionChecker(碰撞检测)之类的封装类,按照我们制定的规范,都重载了<、>、+、-   等一系列运算符,在它们之间使用这种浮点数判断是非常完美的,我把这样的写法写出来是给你用的,不是让你给你的客户去用,懂吗?Top

69 楼OOPhaisky(异化$渴望成功~~)回复于 2006-06-19 20:00:43 得分 0

好热闹啊,来晚了,顶一下!!Top

70 楼steedhorse(晨星)回复于 2006-06-19 22:41:28 得分 1

简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近  
  ==============================================================  
  不是这么说的,并不是“==可能使得两个应该相等的数不相等”,而只是“如果==不成立,我们实际上依然可以认为相等”,如此而已。  
  <=EPSINON怎么可能“使得两个不接近的数判断结果为接近”呢?  
  “a   <=   b”至少不可能在实际上“a   >   b”的时候成立。Top

71 楼howyougen(夫孝,德之本也,教之所由生也)回复于 2006-06-19 23:13:47 得分 0

markTop

72 楼sasdaa(被水淹死的鱼!)回复于 2006-06-20 00:01:31 得分 0

牛角尖!Top

73 楼FreeFice(庄鱼)回复于 2006-06-20 02:04:32 得分 0

To:fireseed(奶油狗【回归Hello   World!】)    
  哈!虽然你举出一大堆的理由,但是依然不能说明你为什么使用模板。因为你所举的例子正确的做法是引入基类,而不是模板。你对大的项目并不了解,在大型项目中通常是限制模板使用的,因为模板有可能使问题变得复杂化,而且在许多情况下并不现实,就说你所举的模板,当为两个不同的类型时,其可否作为相容性判断呢?比方说,float与complex,精度0.01。Top

74 楼haolix(獾猪搂主)回复于 2006-06-20 02:21:06 得分 0

NaN   =   Not   a   Number  
  IEEE中定义了  
  The   IEEE   single   precision   floating   point   standard   representation   requires   a   32   bit   word,   which   may   be   represented   as   numbered   from   0   to   31,   left   to   right.   The   first   bit   is   the   sign   bit,   S,   the   next   eight   bits   are   the   exponent   bits,   'E',   and   the   final   23   bits   are   the   fraction   'F':  
   
      S   EEEEEEEE   FFFFFFFFFFFFFFFFFFFFFFF  
      0   1             8   9                                         31  
   
  The   value   V   represented   by   the   word   may   be   determined   as   follows:  
   
          *   If   E=255   and   F   is   nonzero,   then   V=NaN   ("Not   a   number")  
          *   If   E=255   and   F   is   zero   and   S   is   1,   then   V=-Infinity  
          *   If   E=255   and   F   is   zero   and   S   is   0,   then   V=Infinity  
          *   If   0<E<255   then   V=(-1)**S   *   2   **   (E-127)   *   (1.F)   where   "1.F"   is   intended   to   represent   the   binary   number   created   by   prefixing   F   with   an   implicit   leading   1   and   a   binary   point.  
          *   If   E=0   and   F   is   nonzero,   then   V=(-1)**S   *   2   **   (-126)   *   (0.F)   These   are   "unnormalized"   values.  
          *   If   E=0   and   F   is   zero   and   S   is   1,   then   V=-0  
          *   If   E=0   and   F   is   zero   and   S   is   0,   then   V=0    
  Top

75 楼fanzai(帆仔)回复于 2006-06-20 03:30:43 得分 0

楼主他们老大更年期了,哈哈。Top

76 楼kevinlue(一天一點進步)回复于 2006-06-20 08:35:49 得分 0

不是絕對的Top

77 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 08:36:42 得分 0

大型项目限制模版使用?天大的笑话  
   
  STL算不算大项目?boost算不算大项目?  
   
  至少比你做的MIS系统要大多了吧Top

78 楼FreeFice(庄鱼)回复于 2006-06-20 08:37:49 得分 0

To:   haolix(獾猪搂主)    
  楼主的意思是浮点数也可以使用==进行判断,上面的回答在这一点上是肯定的,只是其判断的结果可能并不同于编程者的想象。原因很简单,所有的类型、精度什么的都是人为的概念,作为机器所面临的永远都是高低电平的变化,也就是所谓的0101,如果不能比较,就不存在什么软件,其差别仅在于比较出来的值是不是设计者所期望的这一点。  
  To:all  
  NaN一样可以比较,原因同上。因此,你搬出来的这个论据不能说明浮点数不能用==比较。这一点,就像我反对将模板技术用于大的项目一样,虽然有人搬出一大堆理由和好处,但是依然没有充分的论据证明那样做是正确的,由于模板会自动的产生程序将许多问题掩盖掉(比如复数比较就不适合用上述模板),因此,我说大项目不采用模板这点,他没给出有力的反驳,他用我可能做MIS就认为我做的项目小,这种不负责的行为,不是讨论技术应有的态度。  
  还有一种观点,认为ERP肯定比MIS大,这种想法也是错的,ERP与MIS的差别并不是代码量的多少,而是应用对象的数据量多少,一个好的MIS代码量超过30万条很正常;相反,ERP超过30万条指令的却并不多见,你能说MIS是小项目吗?在技术讨论上,有必要将心态放平和些,不要为了证明自己正确,将自己不知道的东西来出来吓唬人。在一般项目中,如果是个人开发,用不用模板,那倒确实是自由。Top

79 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 08:40:44 得分 0

你七年C++白学了。  
   
  浮点数的特性确定它不能用作“精确运算”。==对于浮点数的意思是完全相等,但事实上通过运算的浮点数不具备数学上的唯一确定性,也就是说两个在数学上相等的数用浮点数表示并不一定是完全相等,很可能是近似相等。  
   
  float   var   =   1.0f;  
  if(var==1.0f)  
  {  
          ....  
   
  这种代码真不知道楼主怎么学C++的。  
   
  应该用整型或者枚举代替float。  
   
   
   
  不能做精确运算这一点很显然能真正理解的人很少,在编程中,应该认为浮点数永远都是不精确的,永远是近似的表示某个值,即使是float   f   =   1;这个时候都不能认为f就等于1,而只能是近似的等于1,即不会大于2也不会小于0,当运算和逆运算后到底是多少那就只有天知道了。  
   
  浮点数运用最多的地方还是3D渲染和游戏开发。因为这些地方近似运算非常多,一幅三维画面中近处也许要表现几厘米的距离,而远处也许要表现几公里的距离,整型很显然是值域不够的,也完全没有必要,这就是浮点数发挥作用的地方了,对于近处而言,也许几毫米的误差会带来重大影响,而对于远处而言,这个误差就能扩大到几米也不会出问题。Top

80 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 08:43:35 得分 0

很多人只看到了浮点数能表示大数,却忽略了它只是近似表示……。Top

81 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 08:55:31 得分 0

NaN一样可以比较,原因同上。因此,你搬出来的这个论据不能说明浮点数不能用==比较。这一点,就像我反对将模板技术用于大的项目一样,虽然有人搬出一大堆理由和好处,但是依然没有充分的论据证明那样做是正确的,由于模板会自动的产生程序将许多问题掩盖掉(比如复数比较就不适合用上述模板),因此,我说大项目不采用模板这点,他没给出有力的反驳,他用我可能做MIS就认为我做的项目小,这种不负责的行为,不是讨论技术应有的态度。  
  ==========================  
   
  这段话简直就是在XXX,有种永远别用vector。  
   
  一个连函数默认参数都不懂的高手,PF   PF啊  
   
  Top

82 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 08:57:36 得分 0

倒是想听一下您怎么批判STL,洗耳恭听ingTop

83 楼tiaoci(我挑刺,我快乐)回复于 2006-06-20 09:02:03 得分 0

这个世界上没有绝对的事Top

84 楼cutenoob(cute )回复于 2006-06-20 09:04:30 得分 0

markTop

85 楼pappGG(天天向上)回复于 2006-06-20 09:16:35 得分 0

扯远了,关注ingTop

86 楼luckyprg(lucky)回复于 2006-06-20 09:17:24 得分 0

尽量不要用==比较,因为浮点数你无法确定它的精度。  
  0==0.00肯定是false.Top

87 楼usecf(飞鸽)回复于 2006-06-20 09:19:13 得分 0

我同意大家的观点  
  符点数是不能用==这样的符号的Top

88 楼blador(无罪)回复于 2006-06-20 09:32:08 得分 1

觉得Ivony()   说得比较有道理。  
   
  其实完全不用在文字上较真。C/C++语法里面并没有对浮点数使用==做限制,但是通常说得在某某情况下浮点数不能使用==指得是此时使用==程序并不能得到你所期望的结果。  
  以下"能够使用=="指得都是可以得到期望结果。  
   
  看了下楼上的发言,总结起来就是:  
  1.浮点数计算之后的比较不能使用==。如:  
  float   f1   =   3f   *   2;  
  if   (f1   ==   6f)  
  {  
  //不会执行  
  }  
   
  2.单纯的两个浮点数之间是能够使用==。  
  如:  
   
  float   f1   =   GetValueFromSql(); //从数据库中取得一个浮点数3f  
  if   (f1   ==   3f)  
  {  
  //肯定会执行  
  }  
   
  大家以为如何?Top

89 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 09:39:17 得分 0

如果一定要用小数进行精确计算,事实上语言中并没有提供这种功能,可以自己写有理数结构或者定点小数(整型的变种)。Top

90 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 09:41:47 得分 0

2.单纯的两个浮点数之间是能够使用==。  
  如:  
   
  float   f1   =   GetValueFromSql(); //从数据库中取得一个浮点数3f  
  if   (f1   ==   3f)  
  {  
  //肯定会执行  
  }  
   
  大家以为如何?  
   
   
   
  这个也是错的,因为如果GetValueFromSql();把数据库中的3取成了2.999999998,你是不能说这个函数是错误的。况且你根本就不知道数据库中到底是3还是2.9999999998。  
   
  数据库中分得很清楚,只对定点小数保证精确,浮点数仍然是不作任何精确保证。Top

91 楼wls12342004(青青子木)回复于 2006-06-20 09:48:17 得分 0

不支持楼主,直接比较经常会出现莫名其妙的错误,或者说是结果.   这样查问题都很难!Top

92 楼ToolBuilder(~~~~~~党指挥编程~~~~~~)回复于 2006-06-20 10:20:11 得分 1

如果楼主的GetValue确定只返回x.f,那楼主这样比较是正确的,但楼主这样的方式不妥,在软件编写过程中,良好的习惯是必要的,楼主对特殊情况这样处理可能导致以后会养成把浮点数的比较都按这种方式处理,如果按照楼主的GetValue里面的写法,我还不如把GetValue返回一个枚举类型,这样要清晰得多...    
   
   
          计算机语言,特别是C,我觉得没什么是绝对的,但关键要看你的取舍,如果你太注重单一的地方,就会失去全局,林锐的说法我赞同,并不是什么一定,绝对,而是因为你所做的得不偿失...   ...Top

93 楼phommy(石头,竹子,诗)回复于 2006-06-20 10:24:28 得分 0

楼主可以试一下,就算你刚刚赋的常量值接着再取出来,也不一定是相等的  
   
  float   f1=1.1f;  
  if(f1==1.1){;}  
   
  其实和上面的同志的例子一样,  
  float   f   =   2.0/5.0;             //编译器会把2.0/5.0直接计算出来而非运行时计算  
           
          if   (f   ==   0.4)  
          {  
                  cout<<"equal"<<endl;          
          }  
  Top

94 楼mclockw(penny)回复于 2006-06-20 10:37:44 得分 0

把超级小强说的那个老外帖子的内容贴出来:  
   
  A   better   questsion   is   "Why   shouldn't   I   use   ==   to   compare   floats?".     The    
  answer   is:   rounding.   If   you're   comparing   values   that   are   the   result   of   a    
  mathematical   expression   that   "should"   be   equal,   there's   a   very   good   chance    
  that   they   won't   be.  
   
  float   x   =   1.0f;  
  float   y   =   1.0f     /   3;  
  if   (3f   *   y   ==   x)  
  {  
          //   this   code   will   likely   never   run  
  }  
   
  On   the   other   hand,   if   you've   assigned   a   value   from   one   variable   of   type    
  float   to   another   variable   of   type   float,   then   you   can   safely   compare   them    
  for   equality:  
   
  float   x   =   1.0f   /   3.0f;  
  float   y   =   x;  
  if   (x   ==   y)  
  {  
          //   this   code   will   always   run  
  }  
   
  Of   course,   this   is   an   unusual   situation   -   the   normal   recommendation   is   to    
  never   compare   floats   to   equality:   compare   for   an   acceptably   small   difference    
  in   value:  
   
  if   (fabs(x-y)   <   0.00001)  
  {  
          //   ...   this   will   reliably   execute   when   x   and   y   are   "equal"  
  }  
   
  Top

95 楼ahao(天·狼·星星)回复于 2006-06-20 10:45:08 得分 0

怎么都很孔乙己啊?讨论能不能==有什么意义?能,当然能了,因为编译可以通过?尽管结果可能不是你想要的?这样的话,能==又有什么意义?  
  浮点数的比较就是需要根据具体情况,根据要比较的数的精度情况使用不同的误差值来比较。Top

96 楼kefei9627(kefei)回复于 2006-06-20 10:50:31 得分 0

为什么我的程序:  
  #include   <stdio.h>  
   
  int   main()  
  {  
          float   a   =   3.1f;  
          a   =   a   *   2;  
          if   (a   ==   6.2)  
          {  
                  printf("==\n");  
          }  
          else  
          {  
                  printf("!=\n");  
          }          
          getchar();  
  }        
  显示:!=  
   
  而在6.2后面加一个f就能显示==呢?  
  运行环境:dev   c++4.9.9.0   w2k   sp4Top

97 楼ncucf(ncu晨风)回复于 2006-06-20 11:11:13 得分 1

你们老大自以为懂而已!实际上不了解浮点数!  
   
    楼上也有很多脑子不清楚的人,只懂得看教材!  
   
  两个浮点数,一般而言都可以用==来比较的,只要它们都是以浮点数形式来运算!  
  但是,你不应该把一个实数,和浮点数来比较(这才是大家所忌讳的。)  
  浮点数之间为什么不可以比较?我的程序里面,大部分都是这样比较的(唯一的就是有个精度问题,如果你的浮点数,超出了它能表示的精度,可能会导致两个浮点数==比较失败,这是个边缘问题,一般不容易碰到。)    
    大家看看如下代码,是不是浮点数比较????????  
   
  float   f   =   (float)2/5.1;  
  float   dd=(float)(2.0+2.0)/(5.1*2);  
   
          if   (f   ==   dd)  
          {  
              f=3   ;//成功,说明两个浮点数用==没有任何问题  
          }  
   
   
    没有人告诉过你,浮点数是不准确,有随机性的,不可比较的,只是说它能表达的精确位数有限,就像整数也有它能表达的位数。  
  Top

98 楼FlyWithJo(想飞)回复于 2006-06-20 11:21:48 得分 0

因为浮点数的精度有问题,比如说一个2保存为整型的时候,就只是2,但是保存为浮点数的时候在计算机里有可能就是2.000000001或者1.9999999之类的。  
  这是计算机的限制,很难解决,所以你用   (int)2==(float)2的时候,有可能会是false,注意,只是有可能而已!  
  我记得大学里做过测试  
  float   f=1;  
  int   i;  
  for   (i=0;i<500;++i)  
  {  
  printf('%f',f*i);  
  }  
  看到的确实是存在这种情况的(当然,也和不同的编译器有关系),楼主可以试一下。Top

99 楼do_the_best(近我者赤)回复于 2006-06-20 11:29:02 得分 0

某些人说==可以用。没事,你用吧,  
  等系统跑起来之后出现bug你就慢慢查吧。  
   
  不准用==来比较浮点数,  
  这个是写在我们公司的coding规约里面的。Top

100 楼cxz7531(大花猫)回复于 2006-06-20 11:39:04 得分 0

to     bruceteen(周星星)   (   )   信誉:100     2006-6-19   15:11:04     得分:   0      
     
     
         
  re   steedhorse(晨星):  
  你讲得很对,但我也有一些论点,请您斧正一下:  
  如果==不能符合作者要求,那么<=EPSINON,或<EPSINON   也必然不能满足作者要求,因为在   ==   上遇到的问题,在   <=、<   上也一样存在。  
  简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近  
  ------------------------------  
  “因为在   ==   上遇到的问题,在   <=、<   上也一样存在”这种观点是我不能认同的。  
  比如在实际一个场景中,两个相等的数,由于计算误差,使得他们的差值不等于0   ,但最大不会超过百万分之一。两个不相等的数,差值最小也不低于万分之一。百万分之一和万分之一之间有一个不可能区间,那么我们完全可以用“|a-b|<=十万分之一”来判断相等。  
   
  举个例子,亲子鉴定。经过调查研究证实:如果是亲子,基因相似程度都高于90%   ;如果不是亲子,相似程度低于20%   。那么当然可以用相似程度大于70%来作为是否亲子的判断根据。  
     
  Top

101 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 11:40:14 得分 0

我来说句公道话吧  
   
   
  事实上绝大多数用到浮点数的地方(几乎全部)都是经过了一系列算数运算的,而绝大多数用到浮点数比较的地方(几乎全部)在逻辑上都是要忽略小数点后几位的(视精度要求而言)。  
   
  对于浮点数的==的默认行为是比较完全的精度,而这个结果几本上是任何一个程序员都不想要的。  
   
  如果是为了高精度要求,那么==反而成了不利的一面,因为你根本无法控制浮点数本身的精度。  
   
  如果是为了天文、精密仪器、高科技等行业使用,那就应该自行设计一套浮点数表示法,至少应该支持无理数和分数!  
   
  综上所述,针对float和double的==毫无用处,去用一个毫无用处的东西,谁也拦不了你,只不过你是在给你自己找麻烦罢了。Top

102 楼shaoye7(啊呀)回复于 2006-06-20 11:44:22 得分 0

为什么要跟老大对着干呢,这种态度不太合适。Top

103 楼cxz7531(大花猫)回复于 2006-06-20 11:46:46 得分 0

to     bruceteen(周星星)   (   )   信誉:100     2006-6-19   15:11:04     得分:   0      
     
     
         
  re   steedhorse(晨星):  
  你讲得很对,但我也有一些论点,请您斧正一下:  
  如果==不能符合作者要求,那么<=EPSINON,或<EPSINON   也必然不能满足作者要求,因为在   ==   上遇到的问题,在   <=、<   上也一样存在。  
  简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近  
  -------------------  
  补充几句:  
  当我们使用|a-b|<=e来判断是否相等的时候,关键是e的选取。大多数情况下,根据问题的性质,能判断出来,不相等的两个数最小差值e1是多少,相等的两个数产生的最大误差e2是多少,如果e1>e2,那可以取它们之间的任意一个数作为e,比如e=(e1+e2)/2.0。  
  如果不幸   e1<e2   ,那就只好改进算法,降低e2   ,直到小于e1为止。  
   
  误差的估算对于简单问题可以用经验来推断,复杂的问题需要用到误差理论。Top

104 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 11:53:06 得分 0

如果是为了天文、精密仪器、高科技等行业使用,那就应该自行设计一套浮点数表示法,至少应该支持无理数和分数!  
   
  =======================================================  
   
  不可能表示任何无理数,能用有限的字符表示的只有有理数。当然,你可以用根号2或者2的平方根这样的方式来表示无理数,但这只能表示有限的无理数。并非所有的无理数都能如此表示。  
   
  然则所有的有理数都能用两个整数来表示(分子和分母)。  
   
   
  那个晨星纯粹是胡说八道,他那样写程序不死才怪,走在钢丝上说我没掉下去啊,很安全啊,看他杂技能玩多久……Top

105 楼ncucf(ncu晨风)回复于 2006-06-20 11:53:31 得分 0

某些人说==可以用。没事,你用吧,  
  等系统跑起来之后出现bug你就慢慢查吧。  
   
  不准用==来比较浮点数,  
  这个是写在我们公司的coding规约里面的。  
  ______________________________________________  
  如果不懂得一个我们传统思维中的实数和计算机浮点数的区别的公司人员,最好是不要用==来比较两者!  
   
              如果你经常自以为是的一位3/2在计算机里就是1.5这个浮点数,当然会出错,但是你让计算机按照自己的发展,计算6/4和3*2/(8/2)是否相等,绝对是true的。不知道为什么那么多脑子不清楚的人,认为浮点数不能用==比较?  
  不能比较的是你自以为是的   “传统思维中的实数”和计算机根据自己的法则算出的“浮点数”。  
   
    没听说,也没碰到过,两个真正的浮点数,为什么不能用==比较?难道你的电脑出问题,硬件的毛病?  
  (别跟我说浮点数的有效位不够的时候的例子)Top

106 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 11:54:22 得分 0

然则所有的有理数都能用两个有限的整数来表示(分子和分母)。Top

107 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 11:56:22 得分 0

强烈建议晨星同志回去继续学习C语言。  
   
  3/2==1……Top

108 楼gogowhy(123)回复于 2006-06-20 11:56:49 得分 0

mark  
  Top

109 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-06-20 11:56:53 得分 0

错了,是晨风……Top

110 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 12:00:00 得分 0

Ivony   所说大错。  
   
  只要你能用数学符号表示的无理数,程序员总能设计出某种数据结构来表示它,并实现其于它的运算!  
   
  从逻辑上可以证明,基于2进制数学计算的现代计算机完全可以表示任何数学数据结构,除非你的概念只存在于你的脑子里,而无法用数学表示。  
   
  拒我所知,世界上还不存在用数学无法表示的无理数。Top

111 楼Joe_Cai(超级小强)回复于 2006-06-20 12:02:41 得分 0

TO   shaoye7():  
   
  我不是跟老大对着干,我是认为,如果不把这个牛角尖给钻了,我们老大会对我的水平作出错误的判断,从而产生“不信任”,在软件开发的合作过程中,产生“不信任”是会很大程度上影响开发效率的,试想,你给我一个开发任务,但是你对我的开发水平又不太放心,那么我写完了程序,你肯定会花很多时间为我“把关”!古人说“用人不疑,疑人不用”,我觉得我们老祖宗的这句古训用在我们的软件开发中太恰当了!  
   
  过分的谦虚,不是好事!那是中庸之道!你作为开发人员,有必要让你们老大知道你的真实水平,这样他才能作好任务的分配工作!Top

112 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-20 12:04:06 得分 0

还是那句话  
   
  针对float和double的==毫无用处,去用一个毫无用处的东西,谁也拦不了你,只不过你是在给你自己找麻烦罢了。  
  Top

113 楼walkonthesky(★★★★★)回复于 2006-06-20 12:06:41 得分 0

逻辑游戏而已  
   
  粗俗一点的例子  
  就好比人能不能用刀割自己的脖子  
  答案当然是   YES  
  但是割完的结果是不是你想要的,那是不确定的  
  也许是GG了,也许是重伤被送医院救活了  
  也许是怕痛仅仅开了一道小口  
   
  也就是说  
  你可以做,但结果不确定  
  用==比较两个浮点数可以做,但结果不确定  
  就这个意思  
   
  LZ和大家玩逻辑游戏,还没有看出来Top

114 楼cxz7531(大花猫)回复于 2006-06-20 12:13:08 得分 0

to     walkonthesky(★★★★★)   (   )   信誉:100     2006-06-20   12:06:00     得分:   0      
     
     
        逻辑游戏而已  
  .........  
  LZ和大家玩逻辑游戏,还没有看出来  
  ----------------  
  LZ也许是在玩逻辑游戏,但有些人不是,比如这段话:  
  如果==不能符合作者要求,那么<=EPSINON,或<EPSINON   也必然不能满足作者要求,因为在   ==   上遇到的问题,在   <=、<   上也一样存在。  
  简单的讲,如果==可能(其实永远不可能)使得两个应该相等的数不相等了,那么<=EPSINON也会使得两个应该很接近的数判断结果为不接近,或者<=EPSINON会使得两个不接近的数判断结果为接近。  
  你应该怎么回答???  
   
       
     
  Top

115 楼walkonthesky(★★★★★)回复于 2006-06-20 12:28:00 得分 0

不用回答  
  逻辑混乱  
  如果作者是真不明白,建议去看INT和FLOAT在计算机里的具体实现  
   
  如果作者仍然是玩逻辑游戏来赚点击率  
  那可以这样回答  
  运算符号是什么不重要  
  重要的是其代表的逻辑关系  
  你可以自己定义各种符号来表达你需要表达的逻辑关系,这并不重要  
  事实上C++也提供了这样的机制  
   
  你如果一定认为==不能表达[等于]这样一种逻辑关系  
  你按照你理解的方式定义一种叫[FUCK]的逻辑运算符来实现[等于]这样的逻辑关系并不是不可以  
   
  作者如果还要较真  
  就告诉他,你是对的,我们都错了  
  相信面试或者工作能让作者说与大家一样的语言,拥有与大家一致的逻辑  
  虽然其骨子里本不认同大家的观点Top

116 楼ncucf(ncu晨风)回复于 2006-06-20 12:29:41 得分 0

强烈建议晨星同志回去继续学习C语言。  
   
  3/2==1……  
  ________________________________________  
  靠,这我还不知道,你看我上面的例子,都是加了(float)强制转换的!  
     
  看来你还是不懂,为什么不能用==来比较实数和浮点数!Top

117 楼cattlenzq(吃狼的豆腐(不要给分了,散起来真麻烦!))回复于 2006-06-20 12:36:28 得分 0

01来表示浮点数,很多机子的处理是吧后面几位都不做处理,是随机数,它只能保持精度以内的位是相等的,其他的不能保证,所以不同机子会有不同的结果Top

118 楼Joe_Cai(超级小强)回复于 2006-06-20 12:40:04 得分 0

我们单纯一点,只谈技术,不要扯上以为的东西,谢谢~Top

119 楼lkh42002(HAI)回复于 2006-06-20 12:48:10 得分 0

学习    
  收...Top

120 楼For_suzhen(不懂装懂)回复于 2006-06-20 12:52:53 得分 0

支持你们老大,不过现在的情况可能更支持你。因为我试过,可以Top

121 楼fangzhe()回复于 2006-06-20 13:11:24 得分 1

浮点比较  
  ==必须全等,适用于没有运算的,比如float型函数返回的0.0,1.0和1.5。。。  
  但是超出精度的,甚至0和-0都是不等的  
   
  对于经过运算的,  
  fabs(比较值   -   目标值)   <   numeric_limits<double>::epsilon()  
  如果是比较float就是numeric_limits<float>  
  需要#include   <limits>  
  using   namespace   std;  
  这样做移植性较好  
  但是偶尔遇到STL实现的不好的,仍然会出现误判Top

122 楼Juchiyufei(三更半夜我送你回家.总统也许我做不到.今生难得的遇见你,我们就应该在一起.....)回复于 2006-06-20 13:11:24 得分 0

学习Top

123 楼m_blog()回复于 2006-06-20 13:15:44 得分 0

浮点数不能精确比较  
  只能如   x1-x2<0.000001Top

124 楼steedhorse(晨星)回复于 2006-06-20 13:16:18 得分 1

唉,别争了,还是那句话:假如我今天就是想编个程序来验证一下浮点运算的“不精确性”,那么你说我不用“==”用什么?Top

125 楼steedhorse(晨星)回复于 2006-06-20 13:20:36 得分 1

浮点数是绝对可以用“==”比较的,比较下来也肯定是有结果的,只是这个结果不一定符合某些人的预期而已,于是实际中不太会被用到而已。  
  (某些人不包括偶,因为偶对“==”比较浮点数本来就没有任何预期)Top

126 楼Oversense(步步文)回复于 2006-06-20 13:21:33 得分 0

教条主义者认为   需要用   形如   <   A_RANGE   的方法比较浮点数   "相等"  
   
  事实上判断   "相等"   的唯一正确方法就是   ==    
   
  <   A_RANGE   的方法是判断   "小于"  
   
  然而正确的使用   ==   需要对程序和运行它的计算机   的熟悉和了解。  
   
  ==,>,<   这3个运算符在intel机上对应为同一个指令   fcom,然后根据比较结果设FPU状态字的flag而已.(根据出栈和NaN的处理不同还有其他指令)  
   
  比如   a   =   0.2f;   b   =   0.2f;   a   ==   b;   这样写就是可以的。  
     
  但在对浮点数进行大量操作的时候,除非清楚地知道自己在做什么,个人认为不推荐用   ==   而是用   <   A_RANGE   判断一个范围  
   
  这也是对教条主义者(比如项目中的其他人,你的头头,比如林X)的一种"尊重",在有争议的地方取最小子集的,可以实现这种"尊重",比如C++的宏,比如异常,比如匈牙利命名法,比如很复杂的模版。。。  
   
  但是一看到==就惊慌不已,好像天下大乱是不可取的。  
  Top

127 楼Oversense(步步文)回复于 2006-06-20 13:29:58 得分 0

补充一下,   intel32位机上     +0.0   ,   -0.0   是相等的  
   
  我特别翻了一下   IA-32   Software   Developer's   Manual   2   -   Instruction   Set   Reference  
   
  257页,   FCOM/FCOMP/FCOMPP—Compare   Floating   Point   Values   章节  
   
  "The   sign   of   zero   is   ignored,   so   that   –0.0   is   equal   to   +0.0."Top

128 楼steedhorse(晨星)回复于 2006-06-20 13:39:44 得分 1

但是一看到==就惊慌不已,好像天下大乱是不可取的。  
  ================  
  同意,赞成,支持。Top

129 楼steedhorse(晨星)回复于 2006-06-20 13:40:18 得分 1

只要清楚地知道自己正在做什么,怕什么,想用就用。Top

130 楼cg5353(努力学习中)回复于 2006-06-20 13:53:01 得分 0

回帖好多。。  
  只是感觉对于超过浮点数精度的,用==的行为会不可预测Top

131 楼xrascal(横刀夺爱)回复于 2006-06-20 13:55:57 得分 0

别拉我,我真要跳楼了。。。  
  我非跳楼不可。Top

132 楼ncucf(ncu晨风)回复于 2006-06-20 14:10:06 得分 0

只要你不把实数和计算机的浮点数比较,比如写成(float)1/(float)4==0.25就可以。  
  你如果写成float   d=0.25f;  
  if((float)1/(float)4==d)  
  结果肯定是true;  
  比如f=(float)1/(float)25;  
  下断点观察它的值是0.039999999  
  你如果想当然的以为(float)1/(float)25==0.04当然会出错。  
  但是只要你全部都是按照浮点数的变量来处理,按照它的法则,==是肯定不会出错的!  
  (float)1/(float)25==0.04f肯定是为真。(这里0.04f相当于赋给了一个匿名的float变量)  
   
                 
    最顶楼的“天黑黑”就范了个错误,企图用  
    float   f   =   2.0/5.0;  
           
          if   (f   ==   0.4)  
          {  
                  cout<<"equal"<<endl;      
          }  
  证明浮点数不能用==,不知道谁教他不写成2.0f,5.0f,0.4f的。Top

133 楼avalonBBS("︶.︶メ)→( ̄ε ̄メ)回复于 2006-06-20 14:11:56 得分 0

 
   
  瞅瞅Top

134 楼Joe_Cai(超级小强)回复于 2006-06-20 14:17:47 得分 0

我后来也跟老大说,如果是经过运算得到的浮点数,即使我基础再差,人再笨,我也不会用‘==’去和另外一个数比较,因为我根本不知道运算后的结果到底是什么,我跟谁去比啊~  
  Top

135 楼winyin(无名飞非)回复于 2006-06-20 14:24:19 得分 0

钻牛角尖,再钻牛角尖,,,  
   
   
  你没说你开发的是什么软件啊。。。。  
   
   
        原子弹模拟软件?   医疗设备控制软件?  
   
        ==   这个用法有点悬噢。。。Top

136 楼OpenGL_VC()回复于 2006-06-20 14:24:57 得分 0

个人认为浮点的"==",会给系统带来不稳定因素。  
  大多数情况是可以用,但有%0.1的不安全,那就很可能会造成系统的崩溃。Top

137 楼xiaonian_3654(你猜猜(我要打光棍,小乔嫁不了))回复于 2006-06-20 14:27:59 得分 0

winyin(无名飞非)   (   )   信誉:99     2006-06-20   14:24:00     得分:   0      
     
     
        钻牛角尖,再钻牛角尖,,,  
   
   
  你没说你开发的是什么软件啊。。。。  
   
   
        原子弹模拟软件?   医疗设备控制软件?  
   
        ==   这个用法有点悬噢。。。  
       
     
  =============================================================  
  这帮人也就是用C/C++的asp程序员Top

138 楼steedhorse(晨星)回复于 2006-06-20 14:29:32 得分 0

To:ncucf(ncu晨风)  
     
  都写成加f后缀也没用的,这点就不要争了。不信你试试:  
  float   f1   =   1.1f   /   55000.0f;  
  if(f1   ==   0.00002f)   {...}Top

139 楼clane(clane)回复于 2006-06-20 14:52:34 得分 0

计算返回值   绝对不能用"=="   来比较  
   
  其他,绝对可以用"=="来比较  
  Top

140 楼ncucf(ncu晨风)回复于 2006-06-20 14:54:14 得分 1

嗯,的确不对,可能这项操作已经超出float的精度范围了!  
  换成double类型就可以了!  
  (不加f后缀的时候,默认小数就是以double的精度来处理)  
   
  double   f1   =   1.1   /   550.0;  
  double   f2=3.3/(550.0*3);  
  if(f1   ==0.002)  
  {f1=5;  
  }  
  Top

141 楼cxjddd(又是花开时)回复于 2006-06-20 15:03:49 得分 0

任何一个数,都可以与   0   比较。。。Top

142 楼DouDouBug(豆豆)回复于 2006-06-20 15:17:21 得分 0

精度问题  
  Top

143 楼Silenthunter(爱XX 爱XX)回复于 2006-06-20 15:30:20 得分 0

强贴留名Top

144 楼zq_IORI()回复于 2006-06-20 15:34:36 得分 0

楼主认为  
  float   GetValue()  
  {  
  return   1.0f;  
  }  
  if(   1.0f   ==   GetValue()   )  
  {  
   
  }  
  能用?  
  明明自己错了,还在狡辩,你7年怎么混的啊?  
  GetValue()的值还是近似值,  
  即使你  
  float   f   =   0.0f;  
  f还是个近似值,不等于0.0f.  
  不要在狡辩了,结贴吧Top

145 楼pagechen(天外飞来的仙)回复于 2006-06-20 15:36:44 得分 0

请测试1   /   3   ==   2   /   6   ?Top

146 楼pagechen(天外飞来的仙)回复于 2006-06-20 15:38:01 得分 0

浮点   0x400AFFFFFFFF   =   0x39F0A0000000Top

147 楼healer_kx(甘草(楼主揭贴吧,我们这些上班灌水的也不容易))回复于 2006-06-20 15:45:59 得分 5

揭帖的时候,把分数都给我好了。  
   
  我再重申一次,这玩意不是绝对的。。。   。。。但是请不要用==。Top

148 楼theforever(碧海情天)回复于 2006-06-20 15:56:53 得分 1

帖如人名,超强,超级强!太那个罕见了!  
  祝楼ZU工作学习快乐!Top

149 楼clane(clane)回复于 2006-06-20 15:56:56 得分 0

to   zq_IORI:  
  float   GetValue()  
  {  
  return   1.0f;  
  }  
  if(   1.0f   ==   GetValue()   )  
  {  
   
  }  
   
   
  绝对是可以用的.呵呵...太大条了Top

150 楼duduhaha(三人行必有我师)回复于 2006-06-20 15:57:50 得分 0

个人感觉,能做一件事不说明一定能把这件事做好.Top

151 楼theforever(碧海情天)回复于 2006-06-20 15:58:22 得分 0

钻牛角尖的人有的时候就等同于无理强辩、没理搅三分。  
  还是理智点干点正事。Top

152 楼duduhaha(三人行必有我师)回复于 2006-06-20 16:06:34 得分 0

when   ca