Basically, the behavior you get when overflowing integers with subtraction, but for a given number of bits. The obvious way, assuming a signed integer:
This simulates an n bit integer operation:
#include
#include
template< typename T >
T sub_wrap(T a, T b, int nBits)
{
T topBit, mask, tmp;
topBit=T(1) << (nBits-1);
mask=(topBit << 1)-1;
tmp=((a&mask)+((~b+1)&mask))&mask;
if (tmp & topBit) tmp=-((~tmp&mask)+1);
return tmp;
}
int main(int argc, char* argv[])
{
std::cout << sub_wrap< int >(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]))
<< std::endl;
return 0;
}
Results:
$ ./sim 5 6 4
-1
$ ./sim 7 3 4
4
$ ./sim 7 -1 4
-8
$ ./sim -16 28 4
4
$ ./sim -16 28 5
-12
$ ./sim -16 28 6
20
Seems you miscalculated your type size by 1 bit.