Whenever we work with one’s complement or two’s complement, we need to state what the word size is. If there are w bits in the word, then the one’s complement of a number x is obtained by subtracting x from the binary numeral made of w 1s. If w is 16, we use 11111111111111112, which is 65535. Then the one’s complement of x is 11111111111111112−x. Viewing x as a binary numeral (with at most w bits), whatever bits are on in x will be off in 11111111111111112−x, and whatever bits are off in x will be on in 11111111111111112−x. Hence, all the bits are complemented.
C has an operator for the one’s complement; ~x flips all the bits, so it produces the one’s complement of x.
The two’s complement of x is 2w−x, by definition (except that the two’s complement of 0 is 0). 2w equals one plus that binary numeral made of w 1s. For example, 216 = 65535 + 1. Therefore, the two’s complement is one more than the one’s complement. Therefore the two’s complement of x is ~x + 1.
C also has an operator for the two’s complement, for unsigned integers. Unsigned arithmetic is defined to “wrap” modulo 2w; whenever a regular arithmetic result is outside that range, it is brought back into that range by adding or subtracting 2w as needed. The regular arithmetic negation of x would be negative (if x is not zero), so the computed result of -x is −x + 2w = 2w−x, which is the two’s complement of x.
~a. With that, to get the two's complement, we add one to it. That is the basic definition/operation. Whether it overflows or not isn't really an issue for that mechanical operation. It might be an issue with a signed number and what we do with it afterwards, but it isn't for an unsigned number