Signed-to-unsigned conversion occurs when a value of a signed integer type, such as int, is converted to an unsigned integer type, such as unsigned int.
In C, converting an integer value to an unsigned integer type follows a modulo rule. The result is the value congruent to the original value modulo one more than the maximum value of the destination unsigned type.
For an unsigned type with a maximum value of \(U_{\max}\), the conversion is equivalent to:\[ \text{result} = \text{value} \bmod (U_{\max}+1) \]
Example Program #
#include <stdio.h>
int main(void)
{
int positive = 25;
int negative = -25;
unsigned int converted_positive = (unsigned int)positive;
unsigned int converted_negative = (unsigned int)negative;
printf("Original positive = %d\n", positive);
printf("Converted positive = %u\n", converted_positive);
printf("Original negative = %d\n", negative);
printf("Converted negative = %u\n", converted_negative);
return 0;
}
Example Output #
On a common system where unsigned int is 32 bits:
Original positive = 25
Converted positive = 25
Original negative = -25
Converted negative = 4294967271
Explanation #
1. Converting a positive value
int positive = 25;
unsigned int converted_positive = (unsigned int)positive;
The value 25 is representable by unsigned int, so the converted value is also 25.
2. Converting a negative value
int negative = -25;
unsigned int converted_negative = (unsigned int)negative;
The conversion follows the unsigned modulo rule. On a system where UINT_MAX is 4294967295, the calculation is:\[ -25 \bmod 2^{32} = 4294967271 \]
Therefore, the converted value is 4294967271 on that system.
The result is not an error or an overflow exception. It is the defined result of converting the value to an unsigned integer type.
Common Signed-to-Unsigned Conversions #
| Original value | Destination type | Result |
|---|---|---|
25 |
unsigned int |
25 |
0 |
unsigned int |
0 |
-1 |
unsigned int |
UINT_MAX |
-10 |
unsigned int |
UINT_MAX - 9 |
-25 |
unsigned int |
UINT_MAX - 24 |
The exact numerical results depend on the range of the destination unsigned type.
Signed and Unsigned Types Compared #
| Feature | Signed integer | Unsigned integer |
|---|---|---|
| Represents negative values | Yes | No |
| Represents zero | Yes | Yes |
| Represents positive values | Yes | Yes |
| Conversion of a negative value | Depends on destination type | Uses the modulo rule |
| Common format specifiers | %d for int |
%u for unsigned int |
Important Rules #
- Converting a signed integer to an unsigned integer type is well-defined, including when the original value is negative.
- The modulo rule applies to the destination unsigned type’s range.
- A signed-to-unsigned conversion can produce a very large positive value from a negative input.
- Mixing signed and unsigned values in expressions can produce surprising results because the usual arithmetic conversions may convert the signed operand to an unsigned type.
- Use the correct format specifier when printing values:
%dforintand%uforunsigned int.
Key takeaway: Signed-to-unsigned conversion does not preserve negative values as negative numbers. It maps them into the destination unsigned type’s range according to the modulo rule. Be particularly careful when comparing signed and unsigned values or handling negative input.