I am studying c language and there are two different integer types, signed/unsigned.
Signed integers can present both positive and negative numbers. Why do we need unsigned integers then?
I am studying c language and there are two different integer types, signed/unsigned.
Signed integers can present both positive and negative numbers. Why do we need unsigned integers then?
unsigned
types have an extra bit of storage, allowing them a maximum magnitude of 2CHAR_BIT * sizeof(type)-1 for positive values. This is why types like size_t
, which are meant to store sizes of files, strings, arrays, etc. are unsigned.
With signed integers, one bit is reserved for the sign, so if an int
is 32-bits long, you only get 31 bits to store the magnitude of the number. An unsigned int
does not have this restriction; the MSB is used for magnitude as well, but it comes at the expense of no longer being able to be negative.
Signed integer overflow is undefined by the C standard, whereas unsigned integer overflow is guaranteed to wrap-around and reset to zero. For example, the following code invokes undefined behavior in C:
int a = INT_MAX;
a++;
Whereas this is guaranteed to wrap-around back to zero:
unsigned int a = UINT_MAX;
a++;
Unsigned types are generally better for performing bit operations on
One word answer is "range"!
When you declare a signed integer, it takes 4 bytes/ 32 bits memory (on a 32 bit system). Out of those 32 bits, 1 bit is for sign and other 31 bits represent number. Means you can represent any number between -2,147,483,648 to 2,147,483,647 i.e. 2^31.
What if you want to use 2,147,483,648? Go for 8 bytes? But if you are not interested in negative numbers, then isn't it wastage of 4 bytes?
If you use unsigned int, all 32bits represent your number as you don't need to spare 1 bit for sign. Hence, with unsigned int, you can go from 0 to 4,294,967,295 i.e. 2^32
Same applies for other data types.
It's all about memory. They are used to represent a greater number without making use of a larger amount of memory.
Numbers are stored on the computer in binary form. Signed numeric values use a process called two's complement to transform positive numbers into negative ones where the first bit, the one that could represent the highest value is not taken into account for any calculation.
It means that the numeric signed type of your choice can only store a maximum value of N available bits minus 1 bit and the remaining bit will be used to determine the sign of the value, while an unsigned type of your choice can make use of all its available bits to store its value with the drawback of not being able to represent negative values.
There are two/three reasons, given that C must offer the greatest range of possibilities to the programmer.
The first is that an unsigned integer can hold a double (positive) value in respect to its signed counterpart. And we don't want to waste any single bit right?
The second is that a protocol, or some data structure a program must cope with, can use unsigned values, so it is handy to have that data type.
The third is that processors actually have unsigned types, so C language gives them available. May be that there are algorithms which relay on overflow, for example.
There can be still other motivations, probably I don't remember them all.
Personally, I make large use of unsigned integers in embedded applications. For example, using a single unsigned char as an index into a circular buffer of 256 elements, makes it simple and fast to increment the index without checking for overflow, because when the index overflows, it does exactly what I want it to do (reset to zero). Again, there are probably many other situations, I tell just the first that comes to my mind.
The reason is that Integer always has a fixed size. On most systems, an Integer is 32 bits large.
So no matter of having a signed or unsigned Integer, it takes always the same amout of memory. And that's where signed and unsigned differ: the range
Where an unsigned integer has a range of 0 to 4294967295 (2³²-1), the signed integer has a range of -2147483647 to 2147483648