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

Fer*_*eak 3 c c++ floating-point int comparison

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

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;

};
Run Code Online (Sandbox Code Playgroud)

和其他地方:

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!
}
Run Code Online (Sandbox Code Playgroud)

问题是:

  1. ints 上的算术运算结果与float给定的情况进行比较有多安全?

  2. (float)m_intValue1 - (float)m_intValue2 > m_floatValue这种情况有必要吗?

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

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

Joe*_*Joe 5

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

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

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

  4. 见2.和3的答案.


Nik*_*iou 5

二元运算中类型提升的通常规则适用。引用标准(第 5 章表达式)

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

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

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

如果另一个操作数不具有相同的类型,则表达式格式错误。

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

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

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

否则,应在两个操作数上执行积分提升(4.5)