Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Unsigned Integer Ranges and Overflow Detection

Hello! Last time, you converted non-negative integers among decimal, binary, and hexadecimal. Now we’ll put a limit on the number of binary positions available. That limit matters whenever a counter, file size, or arithmetic result must fit in a fixed-width integer: the mathematical answer and the value that can be stored may differ.

In this lesson, you’ll calculate the range of an unsigned integer, decide whether an operation fits, and explain what remains in the available bits when it does not.


How width determines the range

An unsigned integer uses every bit to represent a non-negative value. With bits, there are possible bit patterns. The smallest is all zeros. The largest is all ones: adding the place values of those ones gives

Thus, for a positive width , the representable range is

The upper limit is one less than because zero occupies one of the patterns.

Unsigned width Number of patterns Representable values
4 bits 16 0 through 15
8 bits 256 0 through 255
16 bits 65,536 0 through 65,535
32 bits 4,294,967,296 0 through 4,294,967,295

Last lesson, you saw that leading zeros leave a number’s value unchanged. Here they can communicate its width: 00000101 shows how decimal 5 fits in eight bits, while 0101 shows it in four. Both contain the same value, but their possible maximum values differ.


Addition and the carry beyond the available bits

Binary addition follows the same place-value rule as decimal addition. When a column totals two, write a zero in that column and carry one into the next. A carry within the available bits is ordinary addition; a carry out of the leftmost bit means the sum needs another position.

Watch Binary Addition & Overflow from Computerphile. The first segment develops binary carrying using a sum that fits; the second crosses a four-bit boundary.

Binary Addition & Overflow - Computerphile

Binary Addition & Overflow from Computerphile makes the difference between an internal carry and an outgoing carry visible.

Watch binary addition, following the carries in the four-bit sum of 11 and 3. Then watch the overflow case, focusing on what changes when 1 is added to the four-bit maximum, 15.

For example, four-bit fits, even though carrying occurs during the calculation. But does not fit: four bits end at 15. The complete binary sum needs a fifth bit, while its four rightmost bits are 0000.

The same boundary appears at larger widths. Consider this eight-bit addition:

The drawn binary rows add `11111000` (248) and `00001100` (12), producing a ninth-bit carry and eight remaining bits, `00000100` (4). The image’s decimal operand labels, 242 and 18, do not match its binary rows; both pairs happen to sum to 260.

Checking the image against your conversion skills catches an instructive error: the drawn bits represent , not . Either pair totals 260, but an unsigned eight-bit value can reach only 255. The complete sum is 1 00000100; the eight-bit result retains 00000100, which represents 4. When interpreting a diagram like this, check the operands as well as the final sum.


Decide whether an operation fits

The most reliable overflow test is to calculate the exact mathematical result first, then compare it with the width’s range. For an eight-bit unsigned result, the test is whether the answer lies between 0 and 255, inclusive.

For addition, fits exactly at the boundary; exceeds it. Both operands fit individually, but that does not guarantee their sum fits. The same issue arises with multiplication: exceeds the eight-bit maximum, despite both inputs fitting.

Subtraction can cross the other boundary. The exact result of is , which is below the unsigned minimum of zero. This is often called unsigned underflow, rather than overflow above the maximum. In either case, the exact answer is outside the representable range.

For two unsigned inputs and that already fit, these checks can help when you cannot safely calculate a potentially oversized result in the same fixed-width type:

  • Addition exceeds the maximum when .
  • Multiplication exceeds the maximum when , provided .
  • Subtraction goes below zero when .

These are just range comparisons written so that you can make the decision before storing the result. Multiplication by zero always produces zero.


What unsigned wraparound stores

When an unsigned result does not fit, its stored -bit value consists of the rightmost bits of the exact result. Numerically, that value is the remainder after division by :

For eight bits, the modulus is 256. The earlier addition stores . A result may even pass the boundary more than once: , and . For subtraction, the unsigned eight-bit value corresponding to the exact result is 254, because and 254 differ by 256.

The Overflow section of Cornell’s Introduction & C notes connects this bit-level account to an eight-bit unsigned variable. Read the indicated passage for the distinction it makes between unsigned and signed arithmetic; you do not need to learn the surrounding C syntax yet.

Introduction & C - CS 3410

Read the Overflow section of Cornell’s CS 3410 notes to see an eight-bit unsigned value reach its maximum and return to zero.

In the subsection titled “Overflow,” begin where the notes discuss C’s differing rules for signed and unsigned values. Read the unsigned example, ending with the explanation of the dropped ninth bit. Focus on the transition from 255 to 0; signed arithmetic is a preview for the next lesson, not a rule to apply to unsigned values here.

You can inspect the distinction between exact answer and stored answer with Python. Python integers do not normally wrap at eight bits, so the remainder operation below models an eight-bit unsigned result rather than demonstrating Python’s default integer behavior:

width = 8
modulus = 1 << width
maximum = modulus - 1

calculations = [
    ("addition", 248 + 12),
    ("multiplication", 200 * 3),
    ("subtraction", 3 - 5),
]

for name, exact in calculations:
    if exact < 0:
        status = "underflow"
    elif exact > maximum:
        status = "overflow"
    else:
        status = "fits"

    stored = exact % modulus
    print(f"{name}: exact={exact}, {status}, stored={stored:08b}")

Here, 1 << width calculates . The first output ends in 00000100; the multiplication ends in 01011000 (88); and the subtraction ends in 11111110 (254). Changing width changes the boundaries, though the 08b display format would also need adjusting if you wanted the printed bits padded to a different width.


Key takeaways

An -bit unsigned integer represents 0 through . To detect overflow or underflow, compare the exact arithmetic result with both endpoints—not merely with the operands. If the result is stored in unsigned bits, the stored value is its remainder modulo ; that value need not equal the mathematical answer.

Next, we’ll use fixed-width bits to represent signed integers. The bit patterns will be familiar, but their interpretation and range will change.

Can't find a good explanation? Sign up and we'll make it for you

Sign up