Week 07 Tutorial Questions

Objectives

  1. On a machine with 16-bit ints, the C expression (30000 + 30000) yields a negative result.

    Why the negative result? How can you make it produce the correct result?

  2. Assume that the following hexadecimal values are 16-bit twos-complement. Convert each to the corresponding decimal value.

    1. 0x0013
    2. 0x0444
    3. 0x1234
    4. 0xffff
    5. 0x8000
  3. Give a representation for each of the following decimal values in 16-bit twos-complement bit-strings. Show the value in binary, octal and hexadecimal.

    1. 1
    2. 100
    3. 1000
    4. 10000
    5. 100000
    6. -5
    7. -100
  4. What decimal numbers do the following single-precision IEEE 754-encoded bit-strings represent?

    1. 0 00000000 00000000000000000000000
    2. 1 00000000 00000000000000000000000
    3. 0 01111111 10000000000000000000000
    4. 0 01111110 00000000000000000000000
    5. 0 01111110 11111111111111111111111
    6. 0 10000000 01100000000000000000000
    7. 0 10010100 10000000000000000000000
    8. 0 01101110 10100000101000001010000

    Each of the above is a single 32-bit bit-string, but partitioned to show the sign, exponent and fraction parts.

  5. Convert the following decimal numbers into IEEE 754-encoded bit-strings:

    1. 2.5
    2. 0.375
    3. 27.0
    4. 100.0
  6. Write a C function, six_middle_bits, which, given a uint32_t, extracts and returns the middle six bits.

Revision questions

The following questions are primarily intended for revision, either this week or later in session.
Your tutor may still choose to cover some of these questions, time permitting.

  1. Draw diagrams to show the difference between the following two data structures:

    struct {
        int a;
        float b;
    } x1;
    union {
        int a;
        float b;
    } x2;
    

    If x1 was located at &x1 == 0x1000 and x2 was located at &x2 == 0x2000, what would be the values of &x1.a,   &x1.b,   &x2.a, and   &x2.b?

  2. How large (#bytes) is each of the following C unions?

    1. union { int a; int b; } u1;
      
    2. union { unsigned short a; char b; } u2;
      
    3. union { int a; char b[12]; } u3;
      
    4. union { int a; char b[14]; } u4;
      
    5. union { unsigned int a; int b; struct { int x; int y; } c; } u5;
      

    You may assume   sizeof(char) == 1,   sizeof(short) == 2,   sizeof(int) == 4.

  3. Consider the following C union

    union _all {
       int   ival;
       char cval;
       char  sval[4];
       float fval;
       unsigned int uval;
    };
    

    If we define a variable union _all var; and assign the following value var.uval = 0x00313233;, then what will each of the following printf(3)s produce:

    1.   printf("%x\n", var.uval);
    2.   printf("%d\n", var.ival);
    3.   printf("%c\n", var.cval);
    4.   printf("%s\n", var.sval);
    5.   printf("%f\n", var.fval);
    6.   printf("%e\n", var.fval);

    You can assume that bytes are arranged from right-to-left in increasing address order.