История изменений
Исправление m0rph, (текущая версия) :
Производить вычисления лучше, используя знаковые типы, а битовые операции можно делать только с беззнаковыми (иначе получишь undefined behavior). Довольно часто в существующем C++ коде этим моментам внимание не уделяется вообще: двигают биты в int, мешают unsigned и int в вычислениях, короче полный треш и угар.
Есть мнение, что по возможности везде следует использовать знаковые типы и size_t в STL контейнерах - досадное недоразумение.
Лично я стараюсь везде использовать signed типы и просто преобразую unsigned в signed и наоборот там, где это необходимо. Интересный момент, как именно делать это преобразование. Простой static_cast тупо замаскирует проблему, поэтом я пользуюсь самописным narrow_cast, который бросает исключение в случае, если значение не может быть преобразовано в заданный тип. Можешь нагуглить реализацию narrow_cast (я находил несколько вариантов) или написать сам. Обычно отличия в том, дергается ли внутри assert или бросается исключение.
Исходная версия m0rph, :
Производить вычисления лучше, используя знаковые типы, а битовые операции можно делать только с беззнаковыми (иначе получишь undefined behavior). Довольно часто в существующем C++ коде этим моментам внимание не уделяется вообще: двигают биты в int, мешают unsigned и int в вычислениях, короче полный треш и угар.
Есть мнение, что по возможности везде следует использовать знаковые типы и size_t в STL контейнерах - досадное недоразумение.