关于在C / C ++中比较整数和float / double

时间:2014-03-03 09:32:37

标签: c++ c floating-point comparison int

我有以下代码(随意更改浮动的双倍):

class A
{
    public:
        void setValueFloat(float v) {
              m_floatValue = v / 3.6;  // m/s <-> km/h conversion
        }
        void setValueInt(int v1, int v2) { 
              m_intValue1 = v1; m_intValue2 = v2;
        }

        bool conditionIsOk()
        {
             if(m_intValue1 > m_intValue2)
             {
                  if(m_intValue1 - m_intValue2 > m_floatValue)
                  {
                      return true;
                  }
             }
             return false;
        }

    private:
        int m_intValue1, m_intValue2;
        float m_floatValue;

};

以及其他地方:

A a;
int something = 5; // Intentionally int
int somethingElse = 6; //these are just some numbers, not production data!!!
int moreStuff = 7;

a.setValueFloat(something);
a.setValueInt(somethingElse, moreStuff);
if(a.conditionIsOk())
{
   // Yippee!
}

问题:

  1. 鉴于上述情况,将int上的算术运算结果与float进行比较有多安全?

  2. 这种情况是否需要(float)m_intValue1 - (float)m_intValue2 > m_floatValue

  3. 在C / C ++标准中我可以找到关于这种情况的一行吗?

  4. 默认情况下,对于简单情况m_intValue1 - m_intValue2 > m_floatValue,将执行哪些类型转换? (我怎么能以一种他也看到它(视觉上)的方式向别人展示这一点,“只是相信它有效”是不够的:))

2 个答案:

答案 0 :(得分:5)

  1. 这取决于实际的实现(即使用哪个编译器和哪个架构)。在具有32位int和IEEE754二进制32 float的典型系统上,整数可以精确地表示为+ -2 ^ 24作为浮点数,因此不能用于整个可能的值范围。所以不,一般来说它不安全,但如果整数的使用范围(或者在这种情况下相当差异!)和浮点数被适当限制,则可能是安全的。

  2. 没有!实际上m_intValue1 - m_intValue2 > m_floatValue更好,因为在计算差异之后会发生到float的转换(请参阅上述点的差异说明)。您可以明确并写下static_cast<float>(m_intValue1 - m_intValue2) > m_floatValue,但这不是必需的。

  3. 转换包含在C ++标准的第4章中(参见draft N3242)。特别是4.9浮动积分转换,还要注意5§10“通常的算术转换”,这也适用于比较。由于问题也用C标记,在C标准中(见darft N1570),相应的部分是6.3.1,特别是6.3.1.4和6.3.1.8。

  4. 见2.和3的答案。

答案 1 :(得分:3)

适用于二进制操作中类型提升的通常规则。引用标准(第5章表达式)

  

9.许多期望算术或枚举类型操作数的二元运算符会导致转换和产生   结果类型以类似的方式。目的是产生一个通用类型,它也是结果的类型。

     

此模式称为通常的算术转换,其定义如下:

     

如果任一操作数是作用域枚举类型(7.2),则不执行任何转换;

     

如果另一个操作数的类型不同,则表达式格式不正确。

     

如果任一操作数的类型为long double,则另一个操作数应转换为long double。

     

否则,如果任一操作数为double,则另一个操作数应转换为double。

     

否则,如果任一操作数是浮点数,则另一个操作数应转换为浮点数。

     

否则,应在两个操作数上执行整体促销(4.5)