为了账号安全,请及时绑定邮箱和手机立即绑定

浮点数与浮点文字比较中的奇怪输出

浮点数与浮点文字比较中的奇怪输出

C++ C
梵蒂冈之花 2019-06-01 14:38:28
浮点数与浮点文字比较中的奇怪输出float f = 0.7;if( f == 0.7 )     printf("equal");else     printf("not equal");为什么输出not equal ?这一切为什么要发生?
查看完整描述

4 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

这是因为在你的陈述中

  if(f == 0.7)

0.7被视为双倍。尝试0.7F以确保将该值视为浮点数:

  if(f == 0.7f)

但是,正如Michael在下面的评论中所建议的,您永远不应该测试浮点值的确切相等性。


查看完整回答
反对 回复 2019-06-01
?
米脂

TA贡献1836条经验 获得超3个赞

这个答案是对现有答案的补充:请注意,0.7既不能准确地表示为浮点数(也不能表示为双值)。如果它被准确地表示,那么在转换为浮动,然后返回到双倍时不会丢失信息,这样就不会有这个问题了。

甚至可以说,对于不能准确表示的文字浮点常量,应该有一个编译器警告,特别是当标准对于在运行时是在已设置为该时间的模式下进行舍入,还是在编译时在另一个舍入模式下进行的时候。

所有可以精确表示的非整数都有5作为他们的最后一个十进制数字。不幸的是,相反的情况并非如此:有些数字5作为他们的最后一个十进制数,不能被精确地表示。小整数都可以精确地表示,除以2的幂可以将一个可以表示的数字转换成另一个可以表示的数字,只要你不进入非正态数的范围。


查看完整回答
反对 回复 2019-06-01
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

正如其他评论者所指出的,您面临的问题是,测试浮点数之间的确切等效性通常是不安全的,因为初始化错误或计算中的舍入错误可能会引入一些细微的差异,从而导致=操作符返回false。

更好的做法是做类似的事情

float f = 0.7;if( fabs(f - 0.7) < FLT_EPSILON )
    printf("equal");else
    printf("not equal");

假设Flt_Epsilon已被定义为平台的适当小浮点数。

由于舍入或初始化错误不太可能超过Flt_Epsilon的值,这将为您提供您正在寻找的可靠的等效测试。


查看完整回答
反对 回复 2019-06-01
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

网络上的许多答案都错误地考虑了浮点数之间的上述差异,这仅适用于特殊情况,稳健的方法是查看相对差异,如下所示:

      // Floating point comparison:

        bool CheckFP32Equal(float referenceValue, float value)
        {
           const float fp32_epsilon = float(1E-7);
           float abs_diff = std::abs(referenceValue - value);

           // Both identical zero is a special case
           if( referenceValue==0.0f && value == 0.0f)
              return true;

           float rel_diff = abs_diff / std::max(std::abs(referenceValue) , std::abs(value) ); 

           if(rel_diff < fp32_epsilon)
                 return true;
           else 
                 return false;

        }


查看完整回答
反对 回复 2019-06-01
  • 4 回答
  • 0 关注
  • 550 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信