Fixed-point arithmetic and overflow
Adding and subtracting fixed-width numbers: the carry, overflow, sign and zero flags, how to detect overflow, signed and unsigned comparison from the flags, the width of sums and products, and fixed-point fractions (Q formats).
Why it exists
A computer adds numbers in registers of a fixed width, say 8, 32 or 64 bits. The mathematical sum of two -bit numbers may need bits. When that happens, the hardware cannot raise an exception on its own: it keeps the low bits and sets flags that describe what happened. The same adder circuit is used for unsigned and for signed (2's complement) numbers, so the flags are the only way software can tell whether the answer is meaningful. Almost every GATE question in this area asks one of three things: what is the result in bits, did it overflow (and which kind), or what are the flag values.
Prerequisites
You need the 2's complement system from signed number representation: ranges, negation, and the fact that .
Precise definitions
Fixed-width (modular) arithmetic. An -bit adder computes and a carry bit. The same output bits are the correct result for unsigned operands and for 2's complement operands, provided the true result is within the range of the interpretation.
The four flags. After an addition (or a subtraction, which is addition of the complement) of two -bit words and giving the -bit result :
- C (carry): the carry out of the most significant bit.
- V (overflow): set when the signed result is outside the 2's complement range.
- N (negative): the sign bit of .
- Z (zero): set when all bits of are 0.
Unsigned overflow happens exactly when for an addition: the true sum is at least .
Signed overflow for addition happens exactly when . Three equivalent tests:
- The two operands have the same sign and the result has the opposite sign. (Operands of different sign can never overflow when added.)
- The carry into the sign bit differs from the carry out of the sign bit: .
- The true sum is outside .
For subtraction computed as : overflow happens when and have different signs and the sign of the result differs from the sign of .
Carry and borrow in subtraction. Subtraction is done as . The carry out of this addition is 1 exactly when as unsigned numbers, that is, when there is no borrow. So "carry = NOT borrow". Some processors (ARM) keep this carry as C after a subtraction; others (x86) invert it so that the flag means borrow. A GATE question that asks about the flag will state its convention or the machine.
Comparison from the flags (after computing ):
| Test | Condition |
|---|---|
| unsigned | no carry (with "carry = not borrow") |
| unsigned | carry |
| signed | |
| signed |
The signed tests use rather than alone because after an overflow the sign bit of the wrapped result is wrong; corrects it.
Width rules.
- The sum of two -bit numbers needs at most bits. The sum of unsigned -bit numbers needs at most bits.
- The product of two -bit numbers (signed or unsigned) fits in bits. The only product that needs the very top of the signed range is , which still fits.
- Extra (guard) bits above the operands stop overflow in a long chain of additions.
Fixed-point fractions (Q formats). A fixed-point number stores an integer and agrees in advance that there are bits after the binary point: the value is . Written for integer bits and fraction bits ( includes the sign bit for signed formats). The resolution (distance between neighbouring values) is . Unsigned covers to ; signed covers to . Addition and subtraction of numbers with the same format is just integer addition on the raw values. Multiplication of by gives a raw product with fraction bits (); shift right by to return to , which may overflow.
How it works
Step through six additions of 8-bit numbers. Each shows the operands, the wrapped sum, the carry out of the sign bit, the carry into it, and the overflow flag computed as their exclusive-or. The test file recomputes every value separately.
Fixed-point addition: carry versus overflow: Positive + positive overflows
Computed exactly, not typedWorking
01100100 (100) + 00110010 (50) = 10010110 carry out 0, carry into sign bit 1
Value, format and bits (changed bits in amber)
Step 1
100 + 50 = 150 is above +127, so the result is not representable. The pattern 1001 0110 reads as -106. The tell-tale is two operands with the same sign and a result of the opposite sign: a carry enters the sign bit but nothing leaves it (carry in 1, carry out 0), so V = 1.
The key fact to see in the animation is that carry and overflow are independent. All four combinations occur: () has a carry and no overflow, () has overflow and no carry, () has both, and () has neither. The carry tells you about the unsigned interpretation, the overflow tells you about the signed one, and the same wrapped bit pattern is the result in both.
Worked examples
EX 1Wrapped sums and flags
EasyThe program below does an 8-bit addition the way a CPU does and prints the flags. The first three lines are rows of the animation.
#include <stdio.h>
#include <stdint.h>
/* 8-bit add: returns the wrapped sum and sets the flags the way a CPU does */
static uint8_t add8(uint8_t a, uint8_t b, int *c, int *v, int *n, int *z) {
unsigned wide = (unsigned)a + b;
uint8_t s = (uint8_t)wide;
*c = (int)(wide >> 8);
*v = (int)((~(a ^ b) & (a ^ s)) >> 7 & 1);
*n = s >> 7;
*z = (s == 0);
return s;
}
static void show(int x, int y) {
int c, v, n, z;
uint8_t s = add8((uint8_t)x, (uint8_t)y, &c, &v, &n, &z);
printf("%4d + %4d = %02X C=%d V=%d N=%d Z=%d\n", x, y, s, c, v, n, z);
}
int main(void) {
show(100, 50);
show(-100, -50);
show(-3, 5);
show(127, 1);
show(-1, 1);
int c, v, n, z;
uint8_t d = add8(5, (uint8_t)(~7u + 1), &c, &v, &n, &z);
printf("5 - 7: %02X (%d) carry=%d borrow=%d\n", d, (int8_t)d, c, !c);
d = add8((uint8_t)-100, (uint8_t)(~100u + 1), &c, &v, &n, &z);
printf("-100 - 100: %02X N=%d V=%d N xor V=%d\n", d, n, v, n ^ v);
unsigned q = 0x58, r = 0x30;
unsigned p = q * r;
printf("Q4.4: %.4f * %.4f = %.4f, raw %X, rescaled %X\n", q / 16.0, r / 16.0, p / 256.0, p, p >> 4);
return 0;
}Output:
100 + 50 = 96 C=0 V=1 N=1 Z=0
-100 + -50 = 6A C=1 V=1 N=0 Z=0
-3 + 5 = 02 C=1 V=0 N=0 Z=0
127 + 1 = 80 C=0 V=1 N=1 Z=0
-1 + 1 = 00 C=1 V=0 N=0 Z=1
5 - 7: FE (-2) carry=0 borrow=1
-100 - 100: 38 N=0 V=1 N xor V=1
Q4.4: 5.5000 * 3.0000 = 16.5000, raw 1080, rescaled 108Reading line 1. : (hex 96), which is as a signed byte. Same sign in, different sign out, so ; no carry out of the top bit, so . As unsigned numbers, is the correct sum, so the unsigned interpretation had no overflow.
Reading line 3. with and . Signed result is correct. As unsigned this is , which does not fit in 8 bits, and says so.
Reading line 5. : the carry chain runs through every bit, , , .
EX 2Subtraction as addition, and carry versus borrow
MediumCompute in 8 bits. The complement of 7 is (invert to , add 1). Add: , with no carry out. The result is (the program's line 5 - 7: FE (-2) carry=0 borrow=1). Since as unsigned numbers, a borrow was needed. With the "carry = not borrow" convention the carry flag is 0, and an x86-style flag would show the borrow as 1.
EX 3Signed comparison needs N xor V
MediumIs (8-bit signed)? Compute , which wraps. The program shows the result , so (the wrapped result looks non-negative), but . Then , so the less-than test is true, which is the correct answer. Testing alone would give the wrong answer.
EX 4How wide must the sum be?
GATE level(a) Four 8-bit unsigned numbers are added. The largest total is , which needs 10 bits (). The rule agrees.
(b) A 1000-element array of 8-bit unsigned values is summed. The maximum total is , which needs 18 bits (). The rule gives .
EX 5Fixed-point product overflows
GATE levelUnsigned numbers have range to and resolution . Take and . The raw product is , which has 8 fraction bits (the program prints it as when divided by 256). To return to shift right by 4 to get , which needs 9 bits. The value is above , so the result overflows the format. Truncating to 8 bits would give , which is wrong.
EX 6Which flag answers which question?
GATE levelTwo 8-bit registers hold and .
Unsigned. , . , so the unsigned sum overflows: the wrapped result is with .
Signed. , . The sum is 0, which is correct: (operands of different sign), and .
The same pair of bit patterns therefore gives an unsigned overflow and no signed overflow.
Cheat box
Cheat box
- -bit adder: result , plus the carry out .
- Unsigned overflow of an addition: .
- Signed overflow of an addition: operands have the same sign and the result has the other sign, or equivalently .
- Operands of different signs never overflow when added. For , overflow needs different signs of and .
- Subtraction . Carry out iff unsigned (carry = NOT borrow; x86 stores the borrow).
- Compare after subtraction: iff ; unsigned iff no carry; signed iff .
- numbers of bits sum to at most bits. A product of two -bit numbers fits in bits.
- : value , resolution . Multiply then shift right by .
Traps and GATE patterns
Connections
Across subjects
Within this subject
The adder that produces these flags is built from full adders in adders and subtractors, and the ALU in ALU design exposes them to the program. Booth multiplication computes the -bit product of signed numbers. Floating point avoids this choice of a fixed point position at the price of rounding, see IEEE 754.
PYQs
1 previous year question from your book. I re-solved each one myself (1 by running or simulating, 0 by reasoning only); the book's key is shown next to my answer. All PYQs
Consider the unsigned 8-bit fixed point binary Number System below: b7b6b5b4b3b2b1b0 where the position of the binary point is between b3 and b2. Assume b7 is the most significant bit (MSB). Some of the decimal numbers listed below cannot be represented exactly in the above representation: (i) 31.500 (ii) 0.875 (iii) 12.100 (iv) 3.001 Which one of the following statements is true?
- (a)None of (i), (ii), (iii), (iv) can be exactly represented.
- (b)Only (ii) cannot be exactly represented.
- (c)Only (iii) and (iv) cannot be exactly represented.
- (d)Only (i) and (ii) cannot be exactly represented.
Self-check
Question 1
In 8-bit 2's complement, compute . What are and ?
Show answerHide
and . The sum is above 127. The wrapped result is . No carry leaves the top bit (), so . Both operands are positive and the result is negative, so .
Question 2
In 8-bit 2's complement compute . What are and ?
Show answerHide
This is , out of range. Unsigned: , so the carry out is 1 and the result is . The result sign is positive while both operands were negative, so and .
Question 3
How many bits does the sum of three 6-bit unsigned numbers need at most?
Show answerHide
The maximum is , which needs 8 bits (). The rule gives .
Question 4
After with 8-bit registers, and . Is in the signed sense?
Show answerHide
, so is false, which means . The negative-looking result is a wrapped overflow: for example , gives , which wraps to () with , and indeed .
Revision card
One-screen revision
- -bit add = sum mod plus carry out .
- Unsigned overflow: on addition. Signed overflow: same-sign operands, different-sign result, i.e. at the sign bit.
- Subtract by adding the complement plus 1. Carry out 1 means no borrow.
- Compare: for equal, no-carry for unsigned less, for signed less.
- Sum of values: bits. Product: bits.
- : raw ; multiply, then shift right ; check the range.
References
- ·Mano and Ciletti, Digital Design, 5th ed., Chapter 1 (signed binary numbers, arithmetic addition and subtraction, overflow) and Chapter 4 (binary adder-subtractor)
- ·Hamacher, Vranesic, Zaky, Computer Organization, 5th ed., Chapter 6 Arithmetic (overflow in integer arithmetic)
- ·Patterson and Hennessy, Computer Organization and Design, Chapter 3 Arithmetic for Computers (addition, subtraction and overflow)
Verification
The animation's carry, overflow and wrapped-sum values are computed by scripts/gen-dl-traces.py and recomputed independently in tests/dl-traces.test.ts. The overflow rules, the signed and unsigned comparison rules from the flags (checked over all 65536 pairs of 8-bit operands), the width rules and the Q-format example are brute-force checked in scripts/enum-checks/dl_numbers.py. The C program is compiled and run by npm run verify:c. The carry-after-subtraction convention is stated for both x86 and ARM from memory and flagged for a textbook check; the independent second pass has not been run yet, so the page stays draft. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (conversions, signed ranges and flags, IEEE 754 fields and custom formats, Boolean identities and counts, K-map groups, adder carries, BCD correction, flip-flop conversions, counter sequences and T equations, state reduction, Quine-McCluskey rounds and covers, floating-point alignment and rounding); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)