在复合赋值运算符中进行转换?

时间:2012-06-06 14:45:06

标签: c++

我有一些代码,简化到其本质,归结为:

int x = 5;
x *= 0.5;

使用Visual Studio进行编译时,我得到一个关于可能的数据丢失的警告C4244 - 当然,因为(简化)将int乘以double会导致double被转换为int,从而失去非 - 整数部分。

我的问题是,是否有C ++语法表明这是预期的行为,以便使警告静音(我知道pragma push / pop禁用警告,我认为更清楚地表明这实际上是预期的行为,而且我不只是压制警告。)

长格式是在乘法之后显式转换,如下所示:

x = (int)(x * 0.5);

但复合运算符表示法更容易阅读。

那么,有没有办法像这样投射?我已经尝试将“(int)”放在我能想到的每个位置,但它们似乎都不是有效的C ++ :(

4 个答案:

答案 0 :(得分:2)

而不是乘以0.5,除以2.使用两个int s整数除法并且不会有警告。

如果你真的想乘以浮点数/双打数,请不要使用int来存储结果。

答案 1 :(得分:2)

警告已到位 - 应警告您可能会丢失数据。

任何避免警告的方法都涉及使用明确表达您意图的语法。这可以通过以下方式完成:

  1. 创建一个能够满足您需求的功能。
  2. 不要使用一元运算符。相反,使用二元运算符,并显式截断结果:x = static_cast<int>(x * 0.5);
  3. 使用一元运算符*,您无法轻易地抑制警告,因为该运算符旨在以明确和直接的方式成为用户,不涉及任何转换 - 并且您的情况不符合此要求。所以这是一个的事情,你不能这样做。

答案 2 :(得分:1)

根据OP的评论,你可能最好建议使用<cmath>中的适当函数,具体取决于你想要的舍入行为的种类(偏见/不符合)偏置)。

例如floor通常会偏向舍入(偏向负无穷大,因为它总是选择较低的整数),即floor( -7.5 )会给你-8,你需要滚动 - 如果您想要对称舍入,即希望floor( -7.5 )-7(因为floor( 7.5 )给出7),您自己应该如何。

然而,

round可以调整以产生无偏的舍入。通常情况下,它会从10round( 10.3 )({1}}(或更高)产生11 round( 10.6 )。在中间(tie-breaking)进行舍入仍然存在问题,即round( 10.5 )应提供什么(通常会产生11)。如果此行为不适合您,您可能需要查看一些替代方案,例如Banker's Rounding / Alternate Rounding等。

答案 3 :(得分:0)

乘以int和float的结果是浮点数

如果要将int转换为float,则可能需要对float进行舍入以删除小数值。如果您只是将其强制转换,则可能会出现舍入错误。

例如,此函数进行舍入(还有其他舍入数字的方法):

int round(float x)
{
  return static_cast<int>((x > 0.5) ? ceil(x) : floor(x));
} 

然后你只需要这样称呼它:

  int x = 5;
  float y = 0.33f;
  x = round(x * y);

你有没有警告并且浮动被正确舍入并转换为int

对于具有良好舍入的*=运算符,我没有合适的解决方案,因此使用此解决方案时,您必须替换*=