在复合赋值运算符中强制转换
Casting in a compound assignment operator?
我的代码,简化为本质,归结为:
int x = 5;
x *= 0.5;
使用 Visual Studio 编译它,我收到关于可能丢失数据的警告 C4244 - 当然,因为(简化)将 int 乘以双精度会导致双精度,然后将其转换为 int,丢失非整数部分。
我的问题是,是否有C++语法来指示这是预期行为,以便使警告静音(我知道编译指示按钮/弹出以禁用警告,我认为更清楚地表明这实际上是预期行为,并且我不只是抑制警告)。
长格式是在乘法后显式强制转换,如下所示:
x = (int)(x * 0.5);
但是复合运算符表示法更易于阅读。
那么,有没有办法像这样投射呢?我尝试在我能想到的每个位置都放置"(int)",但它们似乎都无效C++ :(
与其乘以 0.5,不如除以 2。对于两个int
将使用整数除法,并且不会有任何警告。
如果你真的想乘以浮点数/双精度数,不要使用int
来存储结果。
警告已到位 - 您应该收到数据丢失的警告。
避免警告的任何方法都涉及使用明确表达您的意图的语法。这可以通过以下方式完成:
- 创建一个函数,它做你想做的事。
- 不要使用一元运算符。相反,请使用二进制运算符,并显式截断结果:
x = static_cast<int>(x * 0.5);
使用一元运算符*
您无法轻松禁止显示警告,因为该运算符旨在以清晰明了的方式成为用户,不涉及强制转换 - 并且您的案例不满足此要求。所以你不能这样做是一件好事。
根据OP的评论,最好根据您想要的舍入行为类型(有偏见/无偏见)使用<cmath>
中的适当函数。
例如floor
通常进行偏置舍入(偏向负无穷大,因为它总是选择较小的整数),即 floor( -7.5 )
会给你-8
,如果你想要一个对称的舍入,你需要自己滚动,即希望floor( -7.5 )
-7
(如floor( 7.5 )
给出7
)。
但是,可以调整round
以产生无偏的舍入。通常,它会从round( 10.3 )
产生10
,11
从round( 10.6 )
(或更高)产生。中间四舍五入(平局)仍然存在问题,即round( 10.5 )
应该提供什么(它通常会产生11
)。如果此行为不适合您,您可能需要查找一些替代方案,例如银行家的舍入/替代四舍五入等。
int 和浮点数相乘的结果是浮点数。
如果要将 int 转换为浮点数,则可能需要舍入浮点数以删除十进制值。如果只是投射它,则可能会出现舍入误差。
例如,此函数进行舍入(还有其他舍入数字的方法):
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);
而且您没有警告,浮点数已正确舍入并转换为整数。
我没有适合四舍五入的*=
运算符的解决方案,因此使用此解决方案,您将不得不更换*=
。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- C 复合分配和类型转换问题
- 可变模板:表达式列表在函数转换错误中被视为复合表达式
- 寻找Boost转换迭代器的复合特征模式
- C++用户定义的从复合对象到浮点对象的转换
- 在复合赋值运算符中强制转换
- 使用复合赋值运算符解决转换警告
- 复合赋值运算符的类型/类型转换?(例如*=(星形等于))
- 布尔复合赋值中的隐式转换
- 函数强制转换中作为复合表达式处理的表达式列表[-fpermissive]