CS31 Lab 1: Data Representation

Part 1 (written part): Due at the beginning of class Thursday Sept. 13
Part 2 (programming part): Due by 11:59pm Friday, September 14

This lab assignment includes a written part that you will hand in at the beginning of class on Thursday and a programming part that you will submit electronically using handin31 before Friday at 11:59pm.

This lab should be done on your own; no partners.

Before starting each lab, first run update31, which will create the directory structure for your lab assignments and will grab copies of any starting point files included with the assignment.

Assuming that you have a cs31 directory created in your home directory, run update31, then cd into the labs/01 subdirectory and put all your lab 1 work in there (handin31 grabs files from this subdirectory):

$ update31
$ cd cs31/labs/01
$ pwd
/home/your_user_name/cs31/labs/01

Lab 1 Goals:



Part 1. Written Assignment
This part of the lab assignment is written. I suggest, however, that you verify the correctness of your answers using C and/or gdb.

You can either write-up your solutions by hand or write them up in vim (or emacs) and print the resulting file to one of our printers. To print a file created by vim (or emacs) on a CS lab printer use either enscript or lpr:

$ lpr filename
$ enscript -2rG filename
If you write up your answers in vim (or emacs) make sure to not have lines longer than 80 characters (explicitly hit the Enter key to start a new line). If you have lines longer than 80 characters they will either be cut off by the printer or wrapped strangely. One way to ensure this is to work in a terminal 80 characters wide when you run vim so you can see when the currently line is too long and starts to wrap around.

For these problems you are graded on showing how you applied the operation or conversion method we described in class: you must show your work or explain how you got the result to receive credit. You can check your answers for correctness by either writing a C program to do some of the computation and printing of result values or by using gdb's print command. See the weekly lab page for details on using gdb.

Answer the questions below showing your work and/or explaining your answer. For these questions, if a question specifies a number of bits, your answer should be in a corresponding number of digits. For example, if the question asks to add 4 bit values together your answer should be a 4 bit value not a 64 bit one.

  1. What is the largest positive value that can be represented with a 2's compliment 8 bit number?
  2. convert the unsigned 8 bit binary value 10010101 to decimal
  3. convert the signed 8 bit binary value 10010101 to decimal
  4. For the following 8 bit binary values:
    value 1: 01011101
    value 2: 01100101
    
    1. What is the binary representation of the result of adding them together? Does this operation result in overflow?
    2. What is the decimal representation of the resulting addition if the two values are signed 8 bit values?
    3. What is the decimal representation of the resulting addition if the two values are unsigned 8 bit values?
    4. What is the binary representation of the result of subtracting the second from the first? Does this operation result in overflow?
  5. Convert the following 2 byte binary numbers to hexadecimal (shown with spaces between each 4 digits just to make them easier to read):
    1. 0000 0000 0001 1111
    2. 1101 0001 1010 1111
    3. 1110 1101 1011 0010
  6. Convert the following hexadecimal numbers to binary:
    1. 0x10
    2. 0x801
    3. 0xf731
    4. 0xbcad
  7. Convert the following decimal numbers to 8 bit binary and to hexidecimal (2's complement):
    1. 10
    2. -44
    3. 123
    4. -123
  8. Given the following 4 bit binary values, compute the following showing both the binary and decimal result value for each (list the decimal value of both the signed and unsigned interpretation of the resulting 4 bit value):
    1. 1011 | ~(1100)
    2. ~(1011 | 1100)
    3. 1011 & ~(1100)
    4. (0110 | 0000) & 1111
    5. 0110 << 2
    6. 0110 >> 2
    7. 0110 ^ 1100

Part 2. C Programming
You will write a C program that when run, prints out answers to each of the questions in this part. Each answer should include printing out the value of expressions that demonstrate your answer's correctness. For each question, print out a string that is your answer to the question, and then print out some expressions and their results that support your answer to the question. For example, the beginning of a run of your program might look like this (lab1 is the name of the executable here):
$ ./lab1
Question 1: my answer to question 1 is ...
    This can be verified by examining the result of the expression ...
    when x is the int value ... and y is ... the expression is ... 
    when x is ... and y is ... the expression is ...
    ...

Question 2: my answer to question 2 is ...
    This can be 
    ...
See the "Requirements and hints" section below for information about how to do this.

Answer these questions by writing a C program that prints out the answer and prints out example expression(s) that support your answer

Write a C program that answers the following questions, with examples that illustrate your answer. You may want to try printing some values and expressions in gdb in binary, hexadecimal, and decimal to help you figure out good values to test in your C program to ensure you considering all cases.

  1. What is the largest positive value that can be stored in a C short variable?
  2. What is the smallest negative value that can be stored in a C short variable?
  3. What is the maximum positive value that can be stored in a C int variable?
  4. What is the maximum value that can be stored in a C unsigned int variable?
  5. What arithmetic operation is equivalent to left shifting an unsigned int value by 1?
  6. What arithmetic operation is equivalent to left shifting an unsigned int value by 3?
  7. What arithmetic operation is equivalent to right shifting an unsigned int value by 2?
  8. If the value of an expression evaluates to "true" in a C program, its bitwise NOT always evaluates to "false" (T or F)? C's bitwise NOT operator is ~ (e.g. y = ~x)

    C does not have a boolean type, instead numeric expressions are used and different numeric values evaluate to true or false. Try this out:

      int x;
      x = 3;    // try with different values for x: positive, negative, zero  
      if(x) {                 
         printf("%d\n", x); 
      }
    
  9. C's bit-wise OR and C's logical OR when applied to int or unsigned values both result in the identical logical results (i.e. (a || b) evaluates to true(false) iff (a | b) evaluates to true(false) for all values of a and b). (T or F)? Give two examples to support your answer.

    C's bit-wise OR and C's logical OR when applied to int or unsigned values both result in the identical int or unsigned values (i.e. the value of (a || b) is equal to the value of (a | b) for all values of a and b). (T or F)? Give two examples to support your answer.

    Here is some C syntax that may help you get going with this:

       // assume before this point that all variables where declared to be
       // the same type and that x and y were initialized to some values
    
       l = x || y;  // l gets value of applying C's logical OR operator to x and y
       b = x | y;   // b gets value of applying C's bitwise OR operator to x and y
     
       // this is an example of an if-else statement in C (python uses : and
       // indentation, and C uses indentation inside { } to indicate the set
       // of statements associated with the if and with the else parts
       if(l) { 
         printf("l is true\n");
       } else {
         printf("l is false\n");
       }
    
       if(b) { 
         printf("b is true\n");
       } else {
         printf("b is false\n");
       }
    
  10. C's bit-wise AND and C's logical AND when applied two unsigned values always result in identical logical results (either both evaluate to true true or both to false) but do not necessarily evaluate to the same numeric values. (T or F)? Give two examples to support your answer.
      l = x && y;  // && is C's logical AND operator
      b = x & y;   // & is C's bitwise AND operator
    

Requirements and hints for this part

  1. You must use a Makefile to build your program, and your C code should be in a file named lab1.c.

  2. The answer to each question should be implemented as a separate function called by main. Put the main function at the bottom of your lab1.c file. For example, your lab1.c file may be organized like this:
    #include <stdio.h>
    void question1() {
       // question1 function statements go in here
    }
    void question2() {
       // question2 function statements go in here
    }
    ...
    
    int main() {
      question1();  // call the question1 function
      question2();
      ...
    }
    
    See the the weekly lab page for more explanation about functions in C.

    You are welcome to add additional helper functions.

  3. Each answer should contain enough examples to support it. If your answer is "false", this usually means just providing a single counterexample that proves the statement false. If your answer is "true", then find a few different cases that demonstrate your claim. Do not, for example, enumerate every possible int value. For most questions, it should be enough to have 4 or 5 examples to support your answer. Do not have more than 10 for any one question.

  4. Examples in support of your answer must be computed by the C program. For example, don't just print out the string "3 + 6 = 9" instead write C code that computes the expression and prints out its result, like this:
      int x, y;
      x = 3;
      y = 6;
      printf ("%d + %d = %d\n", x, y, (x+y));
    

  5. Your C program, when run, should print out the answer to each question in order, with supporting examples, in an easy to read format. Use formatted printf statements, and do not print out lines that are longer than 80 characters long (break long output up into multiple lines). '\t' is the tab character and '\n' the newline.

  6. Remember that type is important in C, and that if you use different formatting strings to printf, you can print out the same value as different types (for example, if you print out a value using %u you may see a very different value that if you print it out using %d). If you are not seeing the values you expect to see, check printf formatting. Also, examine the program in gdb.

  7. You should use good C programming style. See my "C Style Guide" for examples of commenting code and avoiding line-wrapping.

  8. For C programming help, see my C programming help/links.
Submit

Once you are satisfied with your programs, hand them in by typing handin31 at the unix prompt.

Note: handin31 will not be ready for lab 1 until this weekend

You may run handin31 as many times as you like, and only the most recent submission will be recorded. This is useful if you realize, after handing in some programs, that you'd like to make a few more changes to them.