Учитывая, как представлены отрицательные числа, a - b будет вычислено следующее:
int a, b, c;
// assign to a and b
c = a + (~b + 1); // () not needed, just to show the point
как уже отмечалось в ОП :) Это переключает внимание на реализацию добавления, что, конечно, неправильно. Следующее является странным способом сделать это (только поскольку другие лучшие способы уже даны)
int add1(int a, int b, int *c)
{
int r = *c & 1;
a &= 1; b &= 1;
*c = a&b | a&r | b&r;
return a^b^r;
}
int inv(int a)
{
int i, r = 0;
for(i = 0; i < sizeof(int)*8; i++)
{
r = r<<1 | (a&1);
a >>= 1;
}
return r<<1;
}
int add(int a, int b)
{
int r = 0, i;
int c = 0;
for(i=0; i < sizeof(int)*8; i++)
{
r |= add1(a>>i, b>>i, &c);
r <<= 1;
}
return inv(r);
}
int sub(int a, int b)
{
return add(a, add(~b, 1));
}
(придерживаясь той же идеи, код можно сделать лучше, просто слишком устал, чтобы сделать его лучше)