您好我正在做以下事情:
struct coord{
int col;
};
int main(int argc, char* argv[]) {
coord c;
c.col = 0;
std::vector<coord> v;
for(int i = 0; i < 5; i++){
v.push_back(coord());
}
c.col += -13;
cout << " c.col is " << c.col << endl;
cout << " v size is " << v.size() << endl;
c.col /= v.size();
cout << c.col << endl;
}
我得到以下输出:
c.col is -13
v size is 5
858993456
但是,如果我将分割线更改为c.col /= ((int)v.size());
,我会得到预期的输出:
c.col is -13
v size is 5
-2
为什么会这样?
答案 0 :(得分:5)
这是v.size()
unsigned
的结果。
答案 1 :(得分:4)
问题是vector< ... >::size()
返回size_t
,typedef
整数类型的unigned
。显然,当您使用无符号整数除以有符号整数时会出现问题。
答案 2 :(得分:2)
std :: vector :: size返回size_t,这是一个无符号整数类型,通常是 unsigned int 。当您使用 int 和 unsigned int 执行算术运算时, int 操作数将转换为 unsigned int 执行操作。在这种情况下,-13转换为 unsigned int ,这是一些接近4294967295的数字(以十六进制表示的FFFFFFFF)。然后除以5。
答案 3 :(得分:1)
如上所述,原因是通过首先将有符号值转换为无符号值来执行有符号/无符号除法。
因此,您需要通过手动将无符号值转换为有符号类型来防止这种情况。
v.size()
存在int
可能过大的风险。但由于红利 适合int
,因此当除数大于该值时,除法的结果相当无聊。所以假设2的补码而没有填充位:
if (v.size() <= INT_MAX) {
c.col /= int(v.size());
} else if (c.col == INT_MIN && v.size() - 1 == INT_MAX) {
c.col = -1;
} else {
c.col = (-1 / 2);
}
在C ++ 03中,它的实现定义了负值除以较大的正值是0还是-1,因此有趣(-1 / 2)
。在C ++ 11中,您可以使用0。
要涵盖除2的补码之外的其他表示,您需要以不同方式处理特殊情况。