The 2’s complement of a binary number in C is the way modern computers represent negative integers. In an 8-bit system, +5 is stored as 00000101 and −5 is stored as 11111011 (the 2’s complement of 00000101). Using 2’s complement, subtraction becomes ordinary addition and there is only one representation of zero — which is why every processor since the 1970s has used it.
This program computes the 2’s complement of a binary string entered by the user. The algorithm has two steps: flip all bits (1’s complement), then add 1 to the result.
What Is 2’s Complement — The Two Methods
Method 1 — Flip then add:
- Invert every bit: 0 → 1, 1 → 0 (this gives the 1’s complement)
- Add 1 to the result
Method 2 — Scan from right:
- Copy all bits from right to left until and including the first ‘1’
- Flip all remaining bits to the left
Both methods produce identical results. Method 1 (flip + add) is simpler to implement in code, so that is what the program below uses.
Step-by-Step Example
Find the 2’s complement of 1010:
| Step | Result | Explanation |
|---|---|---|
| Input | 1010 | original binary number |
| 1’s complement | 0101 | flip every bit: 1→0, 0→1, 1→0, 0→1 |
| Add 1 | 0110 | 0101 + 0001 = 0110 |
| 2’s complement | 0110 | verify: 1010 + 0110 = 10000 (carry = overflow ✓) |
Verify: 1010 + 0110 = 10000. The lower 4 bits are 0000, which is exactly what you expect when a number and its 2’s complement are added (sum = 2ⁿ, carrying out the top bit).
Find the 2’s complement of 11100:
| Step | Result |
|---|---|
| Input | 11100 |
| 1’s complement | 00011 |
| Add 1 | 00100 |
| 2’s complement | 00100 |
C Program for 2’s Complement
/* 2's complement of a binary number in C
* Method: flip all bits (1's complement), then add 1.
* Compile: gcc -ansi -Wall -Wextra twos_complement.c -o twos_complement */
#include <stdio.h>
#include <string.h>
int is_valid_binary(const char *s)
{
int i, len = (int)strlen(s);
if (len == 0) return 0;
for (i = 0; i < len; i++)
if (s[i] != '0' && s[i] != '1') return 0;
return 1;
}
void ones_complement(const char *bin, char *ones, int len)
{
int i;
for (i = 0; i < len; i++)
ones[i] = (bin[i] == '0') ? '1' : '0';
ones[len] = '\0';
}
void add_one(char *bin, int len)
{
int i;
for (i = len - 1; i >= 0; i--) {
if (bin[i] == '0') {
bin[i] = '1';
return;
}
bin[i] = '0';
}
/* carry out: all bits wrapped to 0, overflow beyond the field width */
}
int main(void)
{
char bin[40], ones[40], twos[40];
int len, all_zeros, i;
printf("Enter a binary number: ");
scanf("%39s", bin);
if (!is_valid_binary(bin)) {
printf("Error: enter only 0s and 1s.\n");
return 1;
}
len = (int)strlen(bin);
/* edge case: 2's complement of zero is zero */
all_zeros = 1;
for (i = 0; i < len; i++)
if (bin[i] != '0') { all_zeros = 0; break; }
if (all_zeros) {
printf("Input : %s\n", bin);
printf("2's comp : %s (zero is its own 2's complement)\n", bin);
return 0;
}
/* Step 1: 1's complement (flip all bits) */
ones_complement(bin, ones, len);
strcpy(twos, ones);
/* Step 2: add 1 to the 1's complement */
add_one(twos, len);
printf("Input : %s\n", bin);
printf("1's complement : %s\n", ones);
printf("2's complement : %s\n", twos);
return 0;
}
How to Compile and Run
gcc -ansi -Wall -Wextra twos_complement.c -o twos_complement
./twos_complement
Sample Input and Output
Enter a binary number: 1010 Input : 1010 1's complement : 0101 2's complement : 0110
Enter a binary number: 11100 Input : 11100 1's complement : 00011 2's complement : 00100
Enter a binary number: 1111 Input : 1111 1's complement : 0000 2's complement : 0001
Enter a binary number: 10000000 Input : 10000000 1's complement : 01111111 2's complement : 10000000
(10000000 is its own 2’s complement — the 8-bit representation of −128, whose negation overflows the 8-bit range back to −128.)
Code Explanation
- is_valid_binary() — walks the string and rejects any character that is not ‘0’ or ‘1’. Returns 0 immediately on the first bad character.
- ones_complement() — single pass: maps ‘0’ to ‘1’ and ‘1’ to ‘0’ using the ternary operator. Null-terminates the result so it can be used as a C string.
- add_one() — scans right to left. At the first ‘0’, flip it to ‘1’ and return (no carry). If a ‘1’ is found, flip it to ‘0’ and continue (propagate carry). If the loop ends without returning, all bits wrapped to ‘0’ — this is an overflow (e.g., 1’s complement was all 1s, which means the input was all zeros, already handled by the edge case check).
- strcpy(twos, ones) — copies the 1’s complement result before modifying it with add_one, leaving the original
ones[]intact for display. - All-zeros edge case — 2’s complement of 0 is 0. Without this guard, 0000 → ones = 1111 → add_one wraps to 0000 (correct result), but the edge case makes the special handling explicit and instructive.
Why Does add_one Work?
Binary addition with a carry is like decimal addition. When you add 1 to the rightmost bit:
- If it is 0: 0 + 1 = 1, no carry, done.
- If it is 1: 1 + 1 = 10 in binary, write 0 and carry 1 to the left.
The loop stops as soon as it finds a 0 to absorb the carry. If every bit is 1 (e.g., 0000 → 1’s comp → 1111 → add 1 → 10000), the carry propagates out — beyond the stored field width. This is the expected overflow in 2’s complement arithmetic.
What This Program Teaches
- Two-step 2’s complement — flip + add is the canonical algorithm taught in digital electronics and systems programming.
- Carry propagation — the right-to-left loop in add_one mirrors how a hardware adder propagates carry bits, making this a useful analogy for understanding binary adders.
- Buffer-safe input with scanf width —
scanf("%39s", bin)limits input to one less than the array size, preventing buffer overflow. - Edge case handling for all-zeros — explicitly checking degenerate input before applying an algorithm is good defensive coding practice.
- Why 2’s complement — hardware subtracts by adding the 2’s complement:
A − B = A + (~B + 1). No separate subtraction circuit needed, which simplifies CPU design.
Key 2’s Complement Facts
- Adding a number and its 2’s complement always gives a power of 2 (with carry out).
- For an n-bit field, 2’s complement of
x= 2ⁿ − x. - A number with all-1s leading bit is negative in 2’s complement signed representation.
- The minimum signed n-bit value (1000…0) is its own 2’s complement — negating −128 in 8-bit arithmetic still gives −128 (overflow).
Related Programs
- Binary to Decimal in C
- Binary to Decimal, Octal, and Hexadecimal in C
- Decimal to Binary in C
- Arithmetic Operators in C
- Sum of Digits in C
Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
|
C Programming: A Modern Approach — K.N. King (India) |
(US)
Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.