C ++: Деление на vector.size () дает странные результаты

Возможный дубликат:
int делится на unsigned int, вызывая опрокидывание

Привет, я делаю следующее:

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

Почему это?

2

Решение

Это следствие v.size() являющийся unsigned,

Увидеть int делится на unsigned int, вызывая опрокидывание

5

Другие решения

Проблема в том, что vector< ... >::size() возвращается size_t, который является typedef для unigned целочисленный тип. Очевидно, что проблема возникает, когда вы делите целое число со знаком на число без знака.

4

std :: vector :: size возвращает size_t, который является целым типом без знака, обычно без знака int. Когда вы выполняете арифметическую операцию с ИНТ и без знака int, ИНТ операнд преобразуется в без знака int выполнить операцию. В этом случае -13 преобразуется в без знака int, что некоторое число близко к 4294967295 (FFFFFFFF в шестнадцатеричном). И тогда это делится на 5.

2

Как уже говорилось, причина в том, что деление со знаком / без знака выполняется путем первого преобразования значения со знаком в без знака.

Таким образом, вы должны предотвратить это, вручную преобразовав значение без знака в тип со знаком.

Есть риск, что 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, вам нужно по-разному обращаться с особыми случаями.

1
По вопросам рекламы [email protected]