Mystery of Plain, Signed and Unsigned

 

There are two big players to whom this discussion begins with INT and CHAR. 

Now, firstly specification about the compiler I am using from which all the following results are produced:

    g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0


Let's get started,

First we will demystify integers. Integer is an integral type that can represent positive and negative 

 whole numbers including 0  such as -1, -2, -3 … 0 … 10, 4996, 97634 etc. Since we are having infinite 

 negative and positive numbers in mathematics but we are having finite amounts of memory in our 

computer systems. So we have to adopt some method to store different sizes of integers in our

program. For example, in few use cases we might require small sets of integers numbers or in 

 

another we might require large integer values. 


C++ has created 4 different fundamental integer types available for use are as follows:-

  1. short 

  2. int

  3. long 

  4. long long

Different compilers define different sizes of int some might use int = 2 bytes or for others int = 4 bytes.

Following code show what my compiler consider the size of these fundamental types:

   

OUTPUT:

   

   



The key difference between the various integer types is that they have varying sizes -- the 

larger integers can hold bigger numbers.


Till now we have described what is the size of our integer containers. I am referring to these containers 

as what range of integers can I fill in these integer types. “short” contains a shorter range of +ve and -ve 

range of integers whereas “long” contains a larger range.

Whatever will be the range that doesn’t matter both can contain +ve and -ve numbers.


These four fundamental types are further divided into signed and unsigned.



short

short int

signed short

signed short int

These all have the same meaning.

Equivalent type = short int

unsigned short

unsigned short int

Equivalent type = unsigned short int

int 

signed

signed int 

Equivalent type = int

unsigned

unsigned int

Equivalent type = unsigned int

long

long int

signed long

signed long int

Equivalent type = long int

unsigned long

unsigned long int

Equivalent type = unsigned long int

long long

long long int

signed long long

signed long long int

Equivalent type = long long int

unsigned long long

unsigned long long int

Equivalent type = unsigned long long int



Now at last we need to decide what is the range for each integer type in signed and unsigned form.

  • SIGNED INTEGERS

    • By default, integers are signed, which means the number’s sign is preserved. Therefore,

       a signed integer can hold both positive and negative numbers (and 0).

    • Since integers are by default signed so integer types can also take an optional signed 

       

      keyword, which by convention is typically placed before the type name: 

   

    Above signed keyword can be omitted…

   

RANGE OF SIGNED INTEGERS

Range of integer variables is defined by a set of specific values that a data type can hold.

Consider an 8 bit integer that can hold 2^8 = 256 different values. Now we have to decide what is the 

 nature of these 256 different values?


This Range is predefined for the signed integers are as follows:

    An n-bit signed variable has a range of -(2n-1) to 2n-1-1.


For example any 32-bit integer range is -2,147,483,648 to 2,147,483,647.

NOTES: 

  1. "signed" means "to have a sign", ie. positive and negative.



  • UNSIGNED INTEGERS

Unsigned integers are integers that can only hold non-negative whole numbers. To define an

 unsigned integer we need to use unsigned keyword is place before the type:

   

RANGE OF UNSIGNED INTEGERS

    A 1-byte unsigned integer has a range of 0 to 255. Compare this to the 1-byte signed integer range of

 -128 to 127. Both can store 256 different values, but signed integers use half of their range for 

negative numbers, whereas unsigned integers can store positive numbers that are twice as large.

This Range is predefined for the unsigned integers are as follows: 

    An n-bit unsigned variable has a range of 0 to (2n)-1.


NOTE:

  1. When no negative numbers are required, unsigned integers are well-suited for networking and 

    systems with little memory, because unsigned integers can store more positive numbers 

    without taking up extra memory.


Major Issues:

    Since there are possibilities in which we try to fill those contains more than their actual size like what

 happens if we try to assign the value 280 to an 8-bit signed integer? This number is outside the range 

that a 8-bit signed integer can hold. The number 280 requires 9 bits (plus 1 sign bit) to be represented, 

but we only have 7 bits (plus 1 sign bit) available in a 8-bit signed integer. This is called Integer 

overflow, when we try to store a value that is outside the range of the type.

WHERE IS THE DIFFERENCE OF UNSIGNED CHAR AND CHAR?

If it's for storing string data, there's not any difference. If it's for maths, then there's quite a bit.

These 1 byte or 8 bits can store a maximum 256 values. These 256 can either be 0 to 255 or -127 to 127. 

signed and unsigned chars, both occupy 1 byte, but they have different ranges.

In C++ signed char which can hold at least the values -127 to 127.

    unsigned char which can hold at least values 0 to 255.


                             Signed integers

←-------------------------------------------------------------------------->  

|--------------------------------------|-----------Safe range--------------|--------------------------------------|

-127                                        0                                           127                                         255

                                               ←--------------------------------------------------------------------------->

                                                                       Unsigned integers

                                                |         Basic ASCII values      |


 

The basic ASCII values are in range 0 to 127. The rest part of the ASCII is known as extended ASCII.

 Using char or signed char we cannot store the extended ASCII values. By using the unsigned char, 

we can store the extended part as its range is 0 to 255.


The usage of signed char and unsigned char is to store binary data (integers) while char is used to 

store a character of a text (!!!). So the char type signed or unsigned??? Most compilers treat it as 

signed - I guess because of backward compatibility and to make char behave similarly to other integral 

types (for example when you write simply int it behaves as signed int).


In practices, when you see char, it usually means that this variable holds a string of ascii 

characters:

   

but unsigned char, is usually an array of binary data, not a sting:

   


In such case, you shouldn't print it directly using printf or use some string comparison function like

 strcmp. Instead you should print it as hex and for comparing use memcmp, you will have problems 

when there is some unprintable character or 0x00. 


Comparison between Signed Char and Unsigned Char:




Bibliography :-






























CAUTION: These blogs I have created for my personal use only and I am glad if somehow 

these notes may help you to understand the concept which I have discussed. These notes are 

created by reading various other blogs and watching lectures to get a strong grip on the 

concept.

Comments