Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Sunday, May 10, 2015

Signed vs. Unsigned Integers in C

2's complement Encoding

The most common binary encoding technique for integers is called 2's complement. A signed integer is represented with “N” bits will have a range from -2N-1 to 2N-1 – 1.

The encoding algorithm is as follows.

1. The high-order (leftmost) bit of the word is the sign bit. If the sign bit is 1, the number is negative; otherwise, the number is positive.

2. Positive numbers follow the normal binary sequence.

    0 = 000...0002
    1 = 000...0012
          ...

3. In an N-bit word, omitting the sign bit, there are “N-1” bits for the positive integers which can represent the integers from 0 to 2N-1 – 1.

4. To negate an integer, complement all the bits in the word and then add 1 to the result. For example, to form negative integer -9, start with 9 = 000..10012, complement all the bits to get   111..01102, then add 1 to get -9 = 111..01112 = 247.

5. The maximum negative value, -2N-1, does not have a positive equivalent; negating this value produces the same value.

1's complement Encoding

Another encoding scheme which is used for representing integers is 1's complement. In this scheme, each positive number is represented by normal binary encoding. To obtain a negative number, each bit is simply complemented. For example, to form negative integer -9, start with 9 = 000..10012 and complement each bit to get -9 = 111..01102.

The range of numbers that can be represented for a N-bit word is -(2N-1 – 1) to 2N-1 – 1. 1's complement represents 1 less negative value and has both “-0” and “0”.

Sign Magnitude Encoding

The sign magnitude encoding is similar to the 1's complement encoding. To negate an integer, it just complements the sign bit. For example, to form negative integer -9, start with 9 = 000..10012 and complement the sign bit to get -9 = 100..10012.

The range of numbers that can be represented for a N-bit word is -(2N-1 – 1) to 2N-1 – 1. 1's complement represents 1 less negative value and has both “-0” and “0”.

Signed vs. Unsigned

Unsigned integers are always stored using straight binary notation regardless of whether the signed types use 2-s complement, 1-s complement or sign magnitude notation. For example, in 2-s complement notation, the bit pattern 111...111 (n bits long) can represent either “-1” (using the signed notation) or 2N – 1 (using the unsigned notation). The integers from “0” to 2N-1 – 1 are represented identically in both signed and unsigned notations.

Whether an integer is signed or unsigned affects the operations performed on it. All arithmetic operations on unsigned integers behave according to the rules of modular (congruence) arithmetic modulo 2N. For example, adding 1 to the largest value of an unsigned type is guaranteed to produce “0”. The behaviour of overflow is well-defined.

Expressions that mix signed and unsigned integers are often forced to use unsigned operations. When a negative signed integer is promoted to an unsigned integer of the same or larger type, it is first promoted to the signed equivalent of the larger type, then converted to the unsigned value.

The conversion rules are as follows.



Saturday, April 11, 2015

Adding 2 Binary Numbers in C

//This function adds two binary numbers.
void  AddBinaryNumbers(int iarrNumber1[], int iNoOfDigitsInNumber1, int iarrNumber2[], int iNoOfDigitsInNumber2, int iarrSum[], int iNoOfDigitsInResult)
{
   //The loop counter
   int         iLoopCounter                        = 0;
   //The carry over digit
   int         iCarryOverDigit                     = 0;

   //Iterating through the bigger number
   for (; iLoopCounter < iNoOfDigitsInResult; iLoopCounter++)
   {
      //The sum of two digits
      int  iSumOfDigits = iarrNumber1[iLoopCounter] + iarrNumber2[iLoopCounter] + iCarryOverDigit;

      switch (iSumOfDigits)
      {
         case 0:  //The resultant bit is 0.

                  iarrSum[iLoopCounter] = 0;
                  break;

         case 1:  //The resultant bit is 1.

                  iarrSum[iLoopCounter] = 1;
                  break;

         case 2:  //The resultant bit is 0 and the carry over is 1.

                  iarrSum[iLoopCounter] = 0;
                  iCarryOverDigit = 1;
                  break;

         case 3:  //The resultant bit is 1 and the carry over is 1.

                  iarrSum[iLoopCounter] = 1;
                  iCarryOverDigit = 1;
                  break;
      }
   }

   //Computing the last digit if needed
   iarrSum[iNoOfDigitsInResult - 1] = iCarryOverDigit;
}

//The main function
void main()
{
   //The two arrays holding the two numbers
   int     *piarrNumber1                       = NULL;
   int     *piarrNumber2                       = NULL;
   //The array holding the sum of the two input numbers
   int     *piarrSum                           = NULL;
   //The size of the arrays
   int     iNoOfDigitsInNumber1                = 0;
   int     iNoOfDigitsInNumber2                = 0;
   int     iNoOfDigitsInResult                 = 0;
   //The loop counter
   int     iLoopCounter                        = 0;

   do
   {
      //Asking for the number of digits in the first number
      printf("\nEnter the number of digits in the first number.\n");
      scanf("%d", &iNoOfDigitsInNumber1);
      piarrNumber1 = (int *) calloc(iNoOfDigitsInNumber1, sizeof(int));

      //Asking for the user input
      printf("\nEnter the binary digits of the first number separated by space.\n\n");
      for (iLoopCounter = iNoOfDigitsInNumber1 - 1; iLoopCounter >= 0; iLoopCounter--)
         scanf("%d", &piarrNumber1[iLoopCounter]);

      //Verifying the input
      for (iLoopCounter = 0; iLoopCounter < iNoOfDigitsInNumber1; iLoopCounter++)
      {
         if (0 > piarrNumber1[iLoopCounter] || 1 < piarrNumber1[iLoopCounter])
         {
            printf("\nThe digit %d at index %d is not a binary digit.\n", piarrNumber1[iLoopCounter], iLoopCounter + 1);
            free(piarrNumber1);
            piarrNumber1 = NULL;
            break;
         }
      }
   }
   while (!piarrNumber1);

   do
   {
      //Asking for the number of digits in the second number
      printf("\nEnter the number of digits in the second number.\n");
      scanf("%d", &iNoOfDigitsInNumber2);
      piarrNumber2 = (int *) calloc(iNoOfDigitsInNumber2, sizeof(int));

      //Asking for the user input
      printf("\nEnter the binary digits of the second number separated by space.\n\n");
      for (iLoopCounter = iNoOfDigitsInNumber2 - 1; iLoopCounter >= 0; iLoopCounter--)
         scanf("%d", &piarrNumber2[iLoopCounter]);

      //Verifying the input
      for (iLoopCounter = 0; iLoopCounter < iNoOfDigitsInNumber2; iLoopCounter++)
      {
         if (0 > piarrNumber2[iLoopCounter] || 1 < piarrNumber2[iLoopCounter])
         {
            printf("\nThe digit %d at index %d is not a binary digit.\n", piarrNumber2[iLoopCounter], iLoopCounter + 1);
            free(piarrNumber2);
            piarrNumber2 = NULL;
            break;
         }
      }
   }
   while (!piarrNumber1);

   //Allocating sufficient space for the array
   if (iNoOfDigitsInNumber1 < iNoOfDigitsInNumber2)
      iNoOfDigitsInResult = iNoOfDigitsInNumber2 + 1;
   else
      iNoOfDigitsInResult = iNoOfDigitsInNumber1 + 1;
   piarrSum = (int *) calloc(iNoOfDigitsInResult, sizeof(int));

   //Adding the two numbers
   AddBinaryNumbers(piarrNumber1, iNoOfDigitsInNumber1, piarrNumber2, iNoOfDigitsInNumber2, piarrSum, iNoOfDigitsInResult);

   //Displaying the result
   for (iLoopCounter = 0; iLoopCounter < iNoOfDigitsInResult; iLoopCounter++)
      printf("\n%d", piarrSum[iLoopCounter]);
}