我有一些代码,简化到其本质,归结为:
int x = 5;
x *= 0.5;
使用Visual Studio进行编译时,我得到一个关于可能的数据丢失的警告C4244 - 当然,因为(简化)将int乘以double会导致double被转换为int,从而失去非 - 整数部分。
我的问题是,是否有C ++语法表明这是预期的行为,以便使警告静音(我知道pragma push / pop禁用警告,我认为更清楚地表明这实际上是预期的行为,而且我不只是压制警告。)
长格式是在乘法之后显式转换,如下所示:
x = (int)(x * 0.5);
但复合运算符表示法更容易阅读。
那么,有没有办法像这样投射?我已经尝试将“(int)”放在我能想到的每个位置,但它们似乎都不是有效的C ++ :(
答案 0 :(得分:2)
而不是乘以0.5,除以2.使用两个int
s整数除法并且不会有警告。
如果你真的想乘以浮点数/双打数,请不要使用int
来存储结果。
答案 1 :(得分:2)
警告已到位 - 应警告您可能会丢失数据。
任何避免警告的方法都涉及使用明确表达您意图的语法。这可以通过以下方式完成:
x = static_cast<int>(x * 0.5);
使用一元运算符*
,您无法轻易地抑制警告,因为该运算符旨在以明确和直接的方式成为用户,不涉及任何转换 - 并且您的情况不符合此要求。所以这是一个好的事情,你不能这样做。
答案 2 :(得分:1)
根据OP的评论,你可能最好建议使用<cmath>
中的适当函数,具体取决于你想要的舍入行为的种类(偏见/不符合)偏置)。
例如floor
通常会偏向舍入(偏向负无穷大,因为它总是选择较低的整数),即floor( -7.5 )
会给你-8
,你需要滚动 - 如果您想要对称舍入,即希望floor( -7.5 )
为-7
(因为floor( 7.5 )
给出7
),您自己应该如何。
round
可以调整以产生无偏的舍入。通常情况下,它会从10
,round( 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 。
对于具有良好舍入的*=
运算符,我没有合适的解决方案,因此使用此解决方案时,您必须替换*=
。