Для арифметики без знака и маскировки результатов, например:
template<int bits>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) & ((1 << bits) - 1);
}
В более общем случае вы можете использовать оператор по модулю:
template<int modulo>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) % modulo;
}
(Обтекание по n
битамэквивалент модуля 2 ^ n.)
Для арифметики со знаком это немного сложнее;используя маску, вы должны подписать, чтобы продлить результаты (предположим, что дополнение 2).
РЕДАКТИРОВАТЬ: Используя предложение sehe для арифметики со знаком:
template<int bits>
int
sub_wrap( int v, int s )
{
struct Bits { signed int r: bits; } tmp;
tmp.r = v - s;
return tmp.r;
}
Учитывая это, sub_wrap<5>( -16, 28 )
дает-12
(что правильно - обратите внимание, что 28
не может быть представлен как целое число со знаком в 5 битах);sub_wrap<6>( -16, 28 )
дает 20
.