[c] How to cast or convert an unsigned int to int in C?

My apologies if the question seems weird. I'm debugging my code and this seems to be the problem, but I'm not sure.

Thanks!

This question is related to c casting types int unsigned

The answer is


Some explain from C++Primer 5th Page 35

If we assign an out-of-range value to an object of unsigned type, the result is the remainder of the value modulo the number of values the target type can hold.

For example, an 8-bit unsigned char can hold values from 0 through 255, inclusive. If we assign a value outside the range, the compiler assigns the remainder of that value modulo 256.

unsigned char c = -1; // assuming 8-bit chars, c has value 255

If we assign an out-of-range value to an object of signed type, the result is undefined. The program might appear to work, it might crash, or it might produce garbage values.

Page 160: If any operand is an unsigned type, the type to which the operands are converted depends on the relative sizes of the integral types on the machine.

... When the signedness differs and the type of the unsigned operand is the same as or larger than that of the signed operand, the signed operand is converted to unsigned.

The remaining case is when the signed operand has a larger type than the unsigned operand. In this case, the result is machine dependent. If all values in the unsigned type fit in the large type, then the unsigned operand is converted to the signed type. If the values don't fit, then the signed operand is converted to the unsigned type.

For example, if the operands are long and unsigned int, and int and long have the same size, the length will be converted to unsigned int. If the long type has more bits, then the unsigned int will be converted to long.

I found reading this book is very helpful.


If you have a variable unsigned int x;, you can convert it to an int using (int)x.


It's as simple as this:

unsigned int foo;
int bar = 10;

foo = (unsigned int)bar;

Or vice versa...


If an unsigned int and a (signed) int are used in the same expression, the signed int gets implicitly converted to unsigned. This is a rather dangerous feature of the C language, and one you therefore need to be aware of. It may or may not be the cause of your bug. If you want a more detailed answer, you'll have to post some code.


IMHO this question is an evergreen. As stated in various answers, the assignment of an unsigned value that is not in the range [0,INT_MAX] is implementation defined and might even raise a signal. If the unsigned value is considered to be a two's complement representation of a signed number, the probably most portable way is IMHO the way shown in the following code snippet:

#include <limits.h>
unsigned int u;
int i;

if (u <= (unsigned int)INT_MAX)
  i = (int)u; /*(1)*/
else if (u >= (unsigned int)INT_MIN)
  i = -(int)~u - 1; /*(2)*/
else
  i = INT_MIN; /*(3)*/
  • Branch (1) is obvious and cannot invoke overflow or traps, since it is value-preserving.

  • Branch (2) goes through some pains to avoid signed integer overflow by taking the one's complement of the value by bit-wise NOT, casts it to 'int' (which cannot overflow now), negates the value and subtracts one, which can also not overflow here.

  • Branch (3) provides the poison we have to take on one's complement or sign/magnitude targets, because the signed integer representation range is smaller than the two's complement representation range.

This is likely to boil down to a simple move on a two's complement target; at least I've observed such with GCC and CLANG. Also branch (3) is unreachable on such a target -- if one wants to limit the execution to two's complement targets, the code could be condensed to

#include <limits.h>
unsigned int u;
int i;

if (u <= (unsigned int)INT_MAX)
  i = (int)u; /*(1)*/
else
  i = -(int)~u - 1; /*(2)*/

The recipe works with any signed/unsigned type pair, and the code is best put into a macro or inline function so the compiler/optimizer can sort it out. (In which case rewriting the recipe with a ternary operator is helpful. But it's less readable and therefore not a good way to explain the strategy.)

And yes, some of the casts to 'unsigned int' are redundant, but

  • they might help the casual reader

  • some compilers issue warnings on signed/unsigned compares, because the implicit cast causes some non-intuitive behavior by language design


Unsigned int can be converted to signed (or vice-versa) by simple expression as shown below :

unsigned int z;
int y=5;
z= (unsigned int)y;   

Though not targeted to the question, you would like to read following links :


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to casting

Subtracting 1 day from a timestamp date Cast object to interface in TypeScript TypeScript enum to object array Casting a number to a string in TypeScript Hive cast string to date dd-MM-yyyy Casting int to bool in C/C++ Swift double to string No function matches the given name and argument types C convert floating point to int PostgreSQL : cast string to date DD/MM/YYYY

Examples related to types

Cannot invoke an expression whose type lacks a call signature How to declare a Fixed length Array in TypeScript Typescript input onchange event.target.value Error: Cannot invoke an expression whose type lacks a call signature Class constructor type in typescript? What is dtype('O'), in pandas? YAML equivalent of array of objects in JSON Converting std::__cxx11::string to std::string Append a tuple to a list - what's the difference between two ways? How to check if type is Boolean

Examples related to int

How can I convert a char to int in Java? How to take the nth digit of a number in python "OverflowError: Python int too large to convert to C long" on windows but not mac Pandas: Subtracting two date columns and the result being an integer Convert bytes to int? How to round a Double to the nearest Int in swift? Leading zeros for Int in Swift C convert floating point to int Convert Int to String in Swift Converting String to Int with Swift

Examples related to unsigned

Unsigned values in C How to use the unsigned Integer in Java 8 and Java 9? How to convert signed to unsigned integer in python should use size_t or ssize_t Declaring an unsigned int in Java Is unsigned integer subtraction defined behavior? Calculating bits required to store decimal number How to cast or convert an unsigned int to int in C? Difference between signed / unsigned char Can we make unsigned byte in Java