Целые числа без знака реализуют арифметику без знака. Арифметика без знака является арифметикой по модулю. Все значения корректируются по модулю 2 ^ N, где N - количество битов в представлении значения типа без знака.
Проще говоря, арифметика без знака всегда дает неотрицательные значения. Каждый раз, когда выражение должно приводить к отрицательному значению, значение фактически «оборачивается» 2 ^ N и становится положительным.
Когда вы смешиваете целое со знаком и без знака в выражении [sub-], арифметика без знака «выигрывает», то есть вычисления выполняются в области без знака. Например, когда вы делаете col - hw
, это интерпретируется как (unsigned) col - hw
. Это означает, что для col == 0
и hs == 31
вы не получите -31
в результате. Вместо этого вы получите UINT_MAX - 31 + 1
, что обычно является огромным положительным значением.
Сказав это, я должен отметить, что, по моему мнению, всегда полезно использовать неподписанные типы для представления неотрицательных значений. На самом деле, на практике большинство (или, по крайней мере, половина) целочисленных переменных в C / C ++ должны иметь типы без знака. Ваша попытка использовать неподписанные типы в вашем примере вполне оправдана (если вы правильно поняли цель). Более того, я бы использовал unsigned
для col
и row
. Тем не менее, вы должны помнить, как работает беззнаковая арифметика (как описано выше) и писать свои выражения соответственно. Большую часть времени выражение можно переписать так, чтобы оно не пересекало границы беззнакового диапазона, т. Е. В большинстве случаев нет необходимости явно приводить что-либо к типу со знаком. В противном случае, если вам в конечном итоге потребуется работать с отрицательными значениями, правильное приведение к типу со знаком должно решить проблему.