Wednesday, March 4, 2020

TYPES, VALUES, ADDRESSES & STORAGE


Tools needed:
1.    PC running Windows Operating System (OS)
2.    DevC++ (installed)

1.    Memory Storage:

In computer programming, information is stored in a computer memory with different data types. We must know what is to be stored in a computer memory, whether it is a simple number, a letter or a very large number. As we also know, computer memory is organized in bytes, and for these variables with varying information a data type is associated. The minimum amount of memory in computer memory is a byte that can store a small amount of data and managed easily. Every variable is declared with two entities, its type and its name. There are several data types available in C++. The basic built in data types are char, int, float, double and bool.

1.1.         Primitive Data Types in C++:

C++ offers the programmer a rich assortment of built-in as well as user defined data types. Following table lists down seven basic C++ data types:
Several of the basic types can be modified using one or more of these type modifiers:
·         Signed
·         Unsigned
·         Short
·         long

The following table shows the variable type, how much memory it takes to store the value in memory, and what is maximum and minimum value which can be stored in such type of variables.



Figure 1. Table showing memory requirements of Data types

Note: The sizes of variables might be different from those shown in the above table, depending on the compiler and the computer you are using.

2.    Storing Signed/Unsigned Integers

It is imperative that you feel comfortable with binary and hexadecimal conversion. Following sections cover a few basic concepts.


2.1.        Binary and Hexadecimal Conversion

Conversion between binary and hexadecimal notation is straightforward. To convert a binary number, divide it into groups of four bits starting from least significant bit. Add additional zeros to the most significant bit to make the total number of bits a multiple of four. Hexadecimal (or hex) notation is convenient because it saves space. Notice, any number starting with 0x is a hex value.

Dec
  Bin
Hex



0
0b0000
0x0
1
0b0001
0x1
2
0b0010
0x2
3
0b0011
0x3
4
0b0100
0x4
5
0b0101
0x5
6
0b0110
0x6
7
0b0111
0x7
8
0b1000
0x8
9
0b1001
0x9
10
0b1010
0xA
11
0b1011
0xB
12
0b1100
0xC
13
0b1101
0xD
14
0b1110
0xE
15
0b1111
0xF

Table 2. 4-bit Binary-Hexadecimal Conversion

2.2.        Storing Unsigned Integers in Memory

Storing unsigned integers is simple and the procedure is outlined as:
1.            Convert the decimal number to its equivalent binary form.
2.            Add 0's before the most significant bit to fill up 32 bits
3.            Divide number into 4 bytes. LSB corresponds to 1st byte and so on.
4.            Lower bytes go to low memory addresses and higher bytes go to high memory addresses.

2.2.1    Example

Suppose we want to store an unsigned integer with value 27 at address 0x00000010.

27
=
1
1
0
1
1
=
000000000
00000000
00000000
00011011


MSB


LSB

Byte No.
1
2
3
4
   


Memory Map:            
                                   
Address
Data (Bin)
Data (Hex)
Byte No
0x00000010
00011011
1B
1
0x00000011
00000000
00
2
0x00000012
00000000
00
3
0x00000013
00000000
00
4

 

  2.2.2    2’sCompliment Notation

Signed data types like ‘int’ can have negative values. The negative numbers are stored as 2's complement in memory. To calculate 2's complement of a number invert all the bits and add a 1. For example, 0110 (6 in decimal) in inverted form is 1001. By adding 1 we get 1010 which is the 2's complement of 0110. Therefore, -6 would be stored in memory as 1010.



3.    Memory Map in Dev C++

Look minutely at the code below. Save it in lab_07.cpp.
           
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
      long long x= 1234;
      int  y= 1234;

      cout << "x = " << "\t" << right << x << ", &x = " << &x;
      cout << ", x (hex) = " << "\t" << right << hex << x << dec;
cout << endl;
      cout << "y = " << "\t" << right << y << ", &y = " << &y;
      cout << ", y (hex) = " << "\t" << right << hex << y << dec;
      cout << endl;

      return 0;
}

There are few new things to note about the code:
1.    Output stream manipulators hex and dec: hex manipulator shows the integer type variable in hexadecimal (base 16) and dec manipulator shows in decimal. There is a third manipulator oct that can be used to output octal (base 8) equivalent of the number.

2.    Operator & (read 'Address of'): Every variable occupies space (bytes) in memory. These bytes are always contiguous (together in sequence). Each byte has an address to identify it. The address of the first byte (smallest in value) is considered to be the address of the variable.
Addresses (by default) are printed in hexadecimal. So if, for example, the address of the variable x is 4d2, then bytes with addresses 4d2, 4d3, 4d4, and 4d5 are the 4 bytes allocated to the variable x but the smallest of these addresses (or the address of the first byte allocated) is said to be the address of x, i.e., address of x is 4d2.
Use of & with any variable in a cout statement would show the address at which that variable is stored.

Now run the code and note the output. A sample output is shown as follows:

f =         1234, &f = 0x22fe3c, f (hex) =      1234
x =         1234, &x = 0x22fe38, x (hex) =       4d2


float has a size of 4 bytes. Its value is 1234. Its address of 0x22fe3c shows that the first byte of 4 bytes allocated to it has the address 22fe3c. The addresses of other 3 bytes would be 22fe3d, 22fe3e and 22fe3f.


The manipulator hex does not work with float data types.

Similarly, the value of long variable x is 1234 and its address is 22fe38. The value 1234 in decimal is equal to 0x4d2 in hex. Verify it.

The contents of the first byte of variable x of type long would be d2, that of second byte would be 04, that of third byte would be 00 and of fourth would be 00 as well.
The full 32 bit value of variable x would be:
0000 0000 0000 0000 0000 0100 1101 0010

Byte contents of variable x:
Address
Contents in hex
Contents in binary
22fe38
D2
1101 0010
22fe39
04
0000 0100
22fe40
00
0000 0000
22fe41
00
0000 0000




Task # 1:
Make a calculator that gets two integer hexadecimal numbers from user and shows their sum in hexadecimal. The output should be shown as addition sums are done on paper, e.g. a sample output is shown below:

Enter 1st number in hex: FF16
Enter 2nd number in hex: ABC

       FF16
+       ABC
------------
      109D2

Note:
The hex and oct manipulators work with input streams for integer data types as well. Try this code to verify it.

     int x;
     cin >> hex >> x; //provide FF as input
     cout << x;    //the decimal equivalent of hex value FF shown

   Code:
#include <iostream>
#include<iomanip>
using namespace std;
 int main()
            {
                        int x;
                        int n1, n2, sum;
                        cout << " Enter 1st number in hexadecimal : ";
                        cin >>hex>> n1;
                        cout << " Enter  2nd number in hexadecimal : ";
                        cin >>hex>> n2;
                        sum=n1+n2;
                        cout <<" "<<setw(5)<<hex<<n1<<endl;
                        cout<< " + "<<setw(3)<<hex<<n2<< endl;
                        cout << "----------"<<endl;
                        cout << hex<<"  "<<sum<<endl;
                        cout << "----------"<<endl;
                        return 0;
            }  



Task # 2:
Take a random number, for example your roll number. On paper how would this number be stored as an unsigned integer, unsigned short and unsigned long long in memory in hex? Now modify code in lab_07.cpp file to print these values on console.  Does your paperwork match the actual value shown on console?
Code:
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
          unsigned long long  x=1907;      
          unsigned int z=1907;
          unsigned short y=1907;

   
          cout << " unsigned long long Roll Number = " << "\t" << right << x << ", &Roll Number = " << &x;
          cout << ", Roll Number (hex) = " << "\t" << right << hex << x << dec;
cout << endl;
cout << " unsigned short Roll Number = " << "\t" << right << y << ", &Roll Number = " << &y;
          cout << ", Roll Number (hex) = " << "\t" << right << hex << y << dec;
cout << endl;
cout << "unsigned int Roll Number = " << "\t" << right << z << ", &Roll Number = " << &z;
          cout << ", Roll Number (hex) = " << "\t" << right << hex << z << dec;
cout << endl;
         
         
         
          return 0;
}          

Output:
unsigned long long Roll Number =       1907, &Roll Number = 0x6ffe38, Roll Number (hex) =      773
 unsigned short Roll Number =   1907, &Roll Number = 0x6ffe32, Roll Number (hex) =      773
unsigned int Roll Number =      1907, &Roll Number = 0x6ffe34, Roll Number (hex) =      773
Task # 3:
Repeat the previous exercise assuming the number was negative.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
             long long  x=-1907;      
             int z=-1907;
            short y=-1907;

   
            cout << " long long Roll Number = " << "\t" << right << x << ", &Roll Number = " << &x;
            cout << ", Roll Number (hex) = " << "\t" << right << hex << x << dec;
cout << endl;
cout << "  short Roll Number = " << "\t" << right << y << ", &Roll Number = " << &y;
            cout << ", Roll Number (hex) = " << "\t" << right << hex << y << dec;
cout << endl;
cout << " int Roll Number = " << "\t" << right << z << ", &Roll Number = " << &z;
            cout << ", Roll Number (hex) = " << "\t" << right << hex << z << dec;
cout << endl;
           
           
           
            return 0;
}

Output:
long long Roll Number =        -1907, &Roll Number = 0x6ffe38, Roll Number (hex) =     fffffffffffff88d
  short Roll Number =   -1907, &Roll Number = 0x6ffe32, Roll Number (hex) =     f88d
 int Roll Number =      -1907, &Roll Number = 0x6ffe34, Roll Number (hex) =     fffff88d
Task # 4:
Experiment with data types and values given below and report how do they store positive and negative values, if they store numbers. Note your observations here and show them (as well as your code) to the instructor.


bool b = true;
Address
Byte value in hex
0x6ffe3f
               1


bool b = -10;
Address
Byte value in hex
0x6ffe3f
                1


bool b = 0;
Address
Byte value in hex
0x6ffe3f
             0


short s = ______19____;
//initialize with a value of your choice
Address
Byte value in hex
0x6ffe3e
       13
0x6ffe3f
00


short s = __-80_________;
//initialize with a negative value
Address
Byte value in hex
0x6ffe3e
B0
0x6ffe3f
00


long long ll = __________32________________;
//initialize with a value of your choice
Address
Byte value in hex
0x6ffe38
20
0x6ffe39
00
0x6ffe40
00
0x6ffe41
00
0x6ffe42
00
0x6ffe43
00
0x6ffe44
00
0x6ffe45
00


long long ll = ______________-32_________;
//initialize with a negative value
Address
Byte value in hex
0x6ffe38
E0
0x6ffe39
ff
0x6ffe40
ff
0x6ffe41
ff
0x6ffe42
ff
0x6ffe43
ff
0x6ffe44
ff
0x6ffe45
ff




Observations:
Value is first stored in memory addresses accordig to data type for instance long long uses 8 memory addresses and short uses  2 memory addresses.also that when negative numbers are entered all the zero’s in memory addresses are replaced by F’s.

No comments:

Post a Comment

Functions & BASIC FILE I/O

A.    Files : For storage of data for later use, files are used. Files are stored on the Hard Disk Drive (HDD). There are two types of f...