我有以下代码(随意更改浮动的双倍):
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!
}
问题:
鉴于上述情况,将int
上的算术运算结果与float
进行比较有多安全?
这种情况是否需要(float)m_intValue1 - (float)m_intValue2 > m_floatValue
?
在C / C ++标准中我可以找到关于这种情况的一行吗?
默认情况下,对于简单情况m_intValue1 - m_intValue2 > m_floatValue
,将执行哪些类型转换? (我怎么能以一种他也看到它(视觉上)的方式向别人展示这一点,“只是相信它有效”是不够的:))
答案 0 :(得分:5)
这取决于实际的实现(即使用哪个编译器和哪个架构)。在具有32位int
和IEEE754二进制32 float
的典型系统上,整数可以精确地表示为+ -2 ^ 24作为浮点数,因此不能用于整个可能的值范围。所以不,一般来说它不安全,但如果整数的使用范围(或者在这种情况下相当差异!)和浮点数被适当限制,则可能是安全的。
没有!实际上m_intValue1 - m_intValue2 > m_floatValue
更好,因为在计算差异之后会发生到float的转换(请参阅上述点的差异说明)。您可以明确并写下static_cast<float>(m_intValue1 - m_intValue2) > m_floatValue
,但这不是必需的。
转换包含在C ++标准的第4章中(参见draft N3242)。特别是4.9浮动积分转换,还要注意5§10“通常的算术转换”,这也适用于比较。由于问题也用C标记,在C标准中(见darft N1570),相应的部分是6.3.1,特别是6.3.1.4和6.3.1.8。
见2.和3的答案。
答案 1 :(得分:3)
适用于二进制操作中类型提升的通常规则。引用标准(第5章表达式)
9.许多期望算术或枚举类型操作数的二元运算符会导致转换和产生 结果类型以类似的方式。目的是产生一个通用类型,它也是结果的类型。
此模式称为通常的算术转换,其定义如下:
如果任一操作数是作用域枚举类型(7.2),则不执行任何转换;
如果另一个操作数的类型不同,则表达式格式不正确。
如果任一操作数的类型为long double,则另一个操作数应转换为long double。
否则,如果任一操作数为double,则另一个操作数应转换为double。
否则,如果任一操作数是浮点数,则另一个操作数应转换为浮点数。
否则,应在两个操作数上执行整体促销(4.5)