0
0
CComparisonBeginner · 4 min read

Signed vs Unsigned in C: Key Differences and When to Use Each

In C, signed types can represent both positive and negative numbers, while unsigned types represent only zero and positive numbers. This affects the range of values each type can hold and how arithmetic operations behave.
⚖️

Quick Comparison

Here is a quick comparison between signed and unsigned integer types in C:

AspectSignedUnsigned
Value RangeCan be negative, zero, or positiveOnly zero and positive
Default SignYes (default for int)No
Typical Range (int 32-bit)-2,147,483,648 to 2,147,483,6470 to 4,294,967,295
Use CaseWhen negative values are neededWhen only non-negative values are needed
Overflow BehaviorUndefined behavior on overflowWraps around using modulo arithmetic
Memory SizeSame as unsigned of same typeSame as signed of same type
⚖️

Key Differences

Signed integers in C can store both negative and positive numbers because one bit is reserved for the sign (usually the highest bit). This means the range is split between negative and positive values. For example, a 32-bit signed int typically ranges from -2,147,483,648 to 2,147,483,647.

On the other hand, unsigned integers use all bits to represent only non-negative numbers, effectively doubling the maximum positive value compared to signed integers of the same size. For a 32-bit unsigned int, the range is from 0 to 4,294,967,295.

Arithmetic operations behave differently: signed overflow is undefined behavior in C, while unsigned overflow wraps around using modulo arithmetic. This difference is important when choosing the type for variables, especially in loops, counters, or bitwise operations.

⚖️

Code Comparison

This example shows how a signed int handles negative values and overflow:

c
#include <stdio.h>

int main() {
    int a = 2147483647; // max signed int
    int b = a + 1;      // overflow
    int c = -10;        // negative value
    printf("a = %d\n", a);
    printf("b (overflow) = %d\n", b);
    printf("c = %d\n", c);
    return 0;
}
Output
a = 2147483647 b (overflow) = -2147483648 c = -10
↔️

Unsigned Equivalent

This example shows how an unsigned int handles values and overflow differently:

c
#include <stdio.h>

int main() {
    unsigned int a = 4294967295U; // max unsigned int
    unsigned int b = a + 1;        // wraps to 0
    unsigned int c = 10;           // positive value
    printf("a = %u\n", a);
    printf("b (overflow) = %u\n", b);
    printf("c = %u\n", c);
    return 0;
}
Output
a = 4294967295 b (overflow) = 0 c = 10
🎯

When to Use Which

Choose signed types when you need to represent negative numbers, such as temperatures, balances, or differences. Use unsigned types when you know values will never be negative, like sizes, counts, or bit flags, to get a larger positive range and predictable wrap-around behavior.

Be careful with mixing signed and unsigned types in expressions to avoid unexpected results or warnings.

Key Takeaways

Signed types store both negative and positive numbers; unsigned types store only zero and positive numbers.
Unsigned types have a larger positive range but cannot represent negative values.
Signed overflow is undefined behavior; unsigned overflow wraps around modulo the max value plus one.
Use signed when negatives are needed; use unsigned for counts, sizes, or bitwise operations.
Mixing signed and unsigned types can cause bugs; keep types consistent.