How to Perform Binary Subtraction

Subtract binary numbers two ways: the borrow method you'd use on paper and the two's complement method computers use, with negative results explained.

Binary Subtraction: The Rules You Must Know

Binary subtraction removes one binary number from another. Unlike decimal subtraction, where you borrow a group of ten, binary subtraction works in base 2. The rules are simpler to state but easier to get wrong in practice. The four basic results are: 0 minus 0 equals 0, 1 minus 0 equals 1, 1 minus 1 equals 0, and 0 minus 1 requires a borrow from the next higher bit, turning the 0 into 2 (in binary terms) and reducing the higher bit by one. This borrow rule is the heart of the method, and it is the first place people make errors when they subtract by hand. Binary subtraction is not just an academic exercise; it is what your CPU does every time you subtract in any language, from C to Python. Understanding it prevents the sign and borrow mistakes that cost hours of debugging.

Rules: What the Bits Actually Do

The subtraction rules for a single column are exactly four, and memorizing them is the price of entry. Fourth, and the only one that costs you, 0 - 1 = 1 with a borrow of 1 from the next higher column. That borrow works exactly like decimal: when you need to take 1 from a 0, you look left, find the first 1, change it to 0, and turn all the 0s between it and your current column into 1s. This cascading borrow is where beginners lose track, because they try to borrow from an adjacent 0 instead of scanning left to the nearest 1. Borrow from the first 1 you can find to the left, and every 0 in between becomes a 1. Practicing with the examples 1101 (13) minus 0101 (5) equals 1000 (8), and 1010 (10) minus 0110 (6) equals 0100 (4), will make the pattern automatic.

Method 1: How to Subtract Binary Numbers with Borrow, Step by Step

To subtract binary numbers with borrow, write the minuend (the number you are subtracting from) on top and the subtrahend (the number being subtracted) below, aligning the least significant bits on the right. Work from right to left, one column at a time, applying the four rules. If the subtrahend bit is 1 and the minuend bit is 0, you must borrow: scan left, find the first 1, change it to 0, and change every 0 between it and your current column to 1. Move to the next column, remembering that any column where you borrowed now has a minuend bit reduced by 1.

Method 2: Two's Complement Shortcut

The rule is: to compute A - B, take the two's complement of B and add it to A. The two's complement of a number is found by inverting every bit (changing 0 to 1 and 1 to 0, which is the one's complement) and then adding 1 to the result. Invert 0110 to get 1001, then add 1 to get 1010. Now add 1010 (the minuend) and 1010 (the two's complement of the subtrahend): 1010 + 1010 = 10100, but since we are working with 4-bit numbers, we discard the carry out of the most significant bit, leaving 0100 (4). That carry out is not an error. This method works for any pair of numbers where the result is within the representable range. The practical instruction: when subtracting by hand, prefer this method for anything that might be negative, because it removes the need to reason about borrows entirely.

When the Result Is Negative: Interpreting the Answer

When the subtrahend is larger than the minuend, the result is negative, and in two's complement that is not a special case. Using two's complement, take the two's complement of 1010: invert to get 0101, add 1 to get 0110. Add 0110 + 0110 = 1100. The answer is correct, but you must read it as a signed number, not an unsigned one. The rule for reading a negative two's complement number: if the MSB is 1, the number is negative; to find its magnitude, take the two's complement again (invert and add 1). So 1100 inverts to 0011, add 1 gives 0100, which is 4, confirming the value is -4. Also, check the overflow flag: if you add two numbers of opposite signs and the result has a different sign from the minuend, overflow has occurred and the answer is garbage. For 8-bit numbers, the range is -128 to +127, not -127 to +127; that wider negative range is a specific advantage of two's complement over one's complement, which has both +0 and -0.

One's Complement Method: For Courses That Teach It

Some courses and older textbooks teach binary subtraction via one's complement before moving to two's complement, and you should know it for exams even though production code never uses it. The one's complement of a number is simply the bitwise NOT: invert every bit. To subtract A - B using one's complement, you take the one's complement of B, add it to A, and then add any carry out of the MSB back to the result. For example, subtract 0110 (6) from 1010 (10): one's complement of 0110 is 1001. Add 1010 + 1001 = 10011, which is a 5-bit result. Take the carry out (the leading 1) and add it back to the low 4 bits: 0011 + 1 = 0100, which is 4. The problem with one's complement is the dual zero: 0000 is +0 and 1111 is -0, which makes equality checks fail and complicates arithmetic. The range for 8-bit one's complement is -127 to +127, one short of two's complement, and the negative zero is a real bug source in legacy systems. The reason two's complement wins is that it has no negative zero, so the range is a full -128 to +127, and the identity -x = (~x) + 1 always holds.

Borrow vs. Carry and Overflow Flags

The carry flag is not an error for signed arithmetic; it is an error only for unsigned.The practical rule: if you are doing unsigned math, check the carry flag after subtraction; if you are doing signed math, check the overflow flag.

Common Mistakes and How to Avoid Them

The most common failure in binary subtraction is sign extension error: taking an 8-bit signed value like -1 (0xFF) and widening it to 16 bits without sign-extending, which turns it into 255 (0x00FF) instead of -1. Always sign-extend a negative number when widening: replicate the MSB into the new high bits. The second mistake is confusing logical and arithmetic shifts: in C, a right shift of a negative number is implementation-defined per C17 6.5.7, so on GCC and Clang it sign-extends (arithmetic), but on some old or unusual compilers it might zero-fill (logical), and the standard does not require it. The third mistake is using bitwise NOT (~) for logical negation: ~0 is -1, not 0, so an if (~x) test is true for x=0, which is the opposite of intent. Always size the mask to the variable. For unsigned, watch carry.

Verifying Your Answer Without a Calculator

After you subtract binary numbers by hand, verify the result by converting to decimal and back, but do it quickly: for each binary number, write the decimal value, subtract, then convert the result to binary. For negative results, convert the two's complement result to decimal by inverting and adding 1 to get the magnitude, then prefix a minus sign. The fastest cross-check for any addition or subtraction is to compute the decimal in your head; binary arithmetic is mechanical, so a single decimal sanity check catches 90% of errors. When you have a borrow, recheck the column where the borrow happened, because that is where most mistakes live.

Weight Explanation

Two's complement is not a trick; it is a positional notation where the most significant bit has a negative weight. In an 8-bit number, the MSB is worth -128, not +128, so 10000000 is -128, and 11111111 is -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1. This single change makes subtraction identical to addition, because A - B = A + (~B + 1), and the hardware needs only an adder, not a separate subtractor. The identity -x = (~x) + 1 is the foundation: to negate a number, invert all bits and add one, and it always works, including for zero, which has no negative counterpart. This is why the range of an 8-bit signed integer is -128 to +127, not -127 to +127; the extra negative number exists because there is no -0. One's complement and sign-magnitude both have a negative zero, which wastes a bit pattern and breaks equality. The practical takeaway: when you see a negative binary number, think of the MSB as a negative weight, and the arithmetic becomes as simple as decimal.

Who This Subject Suits and Who Should Skip It

This subject suits programmers who debug at the bit level, embedded developers who manipulate registers, and researchers who read memory dumps or parse binary protocols. If you debug signed integers, check the carry flag, or work with bitmasks, this is your daily bread, and the two's complement method is non-negotiable. It also suits students in computer architecture or digital logic courses, where the full-adder sum equation S = A XOR B XOR Cin and carry equation Cout = (A AND B) OR (Cin AND (A XOR B)) are required. It does not suit a web developer building a CRUD app in a high-level framework, where the language hides the bits behind integers and you never see a borrow. The subject is overrated for anyone who has never hit a sign-extension bug or an overflow flag; for them, it is an intellectual curiosity, not a tool. Skip it if you have no interest in why -128 exists or why Python's ~5 is -6, because that is the payoff, and if it does not excite you, the prose will not either. But if you have ever wasted an hour on a wrong subtraction, this is the guide that saves you the next one.

Common Questions

What is the difference between carry and overflow flags in subtraction?

The carry flag is set when a borrow occurs, indicating unsigned underflow, so the result is wrong for unsigned operands. The overflow flag is set when the operands have opposite signs and the result sign differs from the minuend, indicating signed overflow. For signed arithmetic, watch overflow; for unsigned, watch carry.

How do I right-shift a negative number in C portably?

Per C17 6.5.7, right shift of a negative signed value is implementation-defined. GCC and Clang do arithmetic shift, sign-extending, but the standard does not require it. For portable code, cast to unsigned and shift, or use a condition to sign-extend manually.

Why does Python's ~5 give -6?

Python uses infinite-precision two's complement, so bitwise NOT inverts all bits and subtracts 1 from the value, giving ~x = -x - 1. Thus ~5 = -6. This works because Python emulates sign-extension indefinitely, so -1 >> 1 is -1, and -1 & 0xFF is 255.

When I subtract 0 from 1 in binary, why do I get 1 with a borrow?

In the ones column, 0 - 1 requires a borrow from the next higher bit. If the minuend has a 1 to the left, you change it to 0 and the 0 in your column becomes 2, so 2 - 1 = 1. If no 1 exists, the result is negative, handled by two's complement.