4

我的代码简化为:

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

4 回答 4

3

不是乘以 0.5,而是除以 2。将使用 2int的整数除法,并且不会出现警告。

如果您真的想乘以浮点数/双精度数,请不要用于int存储结果。

于 2012-06-06T14:47:08.300 回答
2

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

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

  1. 创建一个执行您想要的功能。
  2. 不要使用一元运算符。相反,使用二元运算符,并显式截断结果:x = static_cast<int>(x * 0.5);

使用一元运算符*,您无法轻松抑制警告,因为该运算符旨在以清晰直接的方式成为用户,不涉及强制转换 - 而您的案例不满足此要求。所以你不能这样做是一件好事

于 2012-06-06T14:53:00.830 回答
1

根据 OP 的评论,最好建议您使用适当的函数,<cmath>具体取决于您想要的舍入行为类型(有偏/无偏)。

例如floor,通常会进行有偏舍入(偏向负无穷大,因为它总是选择较低的整数),即floor( -7.5 )会给你-8,如果你想要一个对称舍入,你需要自己滚动,即想要floor( -7.5 )-7floor( 7.5 )给定7)。

round但是可以调整以产生无偏的舍入。通常,它会产生10from round( 10.3 )11from round( 10.6 )(或更大)。在中间(平局)四舍五入仍然存在问题,即round( 10.5 )应该提供什么(它通常会产生11)。如果这种行为不适合您,您可能需要查看一些替代方案,例如银行家舍入/替代舍入等。

于 2012-06-06T15:04:57.190 回答
0

int 和 float 相乘的结果是 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);

而且您没有任何警告,并且float 已正确舍入并转换为 int

对于具有良好舍入的操作员,我没有合适的解决方案*=,因此使用此解决方案您将不得不替换*=.

于 2012-06-06T15:03:27.980 回答