Integer Bases Solutions

back to the problems

p1 (base conversions)

Complete the following table by hand. For binary, write 8 digits, padding with leading zeroes if necessary. Note that the underscore is there purely for readability.

Decimal Binary Hexadecimal
1 0b0000_0001 0x1
21 0b0001_0101 0x15
129 0b1000_0001 0x81
30 0b0001_1110 0x1e

p2 (conversions in C (or not?))

Confused Cornelius posts the following question on EdStem:

I am trying to write a function that takes in an int and converts it to hex. Here's what I've gotten so far:

int convert_to_hex(int num) { // I'm stuck here...

I read over the slides and notes about doing decimal-hexadecimal conversions but I'm still confused. I can code the arithmetic, but I'm not sure what my final result should really be...?

Help Cornelius out by making a reply to his Ed question.

Hi Cornelius - I don't think what you're trying to do makes sense to do in C! I think you're assuming your function takes in a base 10, decimal integer - but decimal and hexadecimal are just written representations of an integer value. C functions just take in integer values, agnostic of any base.

The base only matters when we try to print out the integer. You can use printf to specify what base (among other options) you want the integer to be printed out as - %d for decimal and %x for hexadecimal.

p3 (base conversions using gdb)

Complete the following table with the help of gdb. Please don't use some random website that you found on Google. You know who you are.

For binary, write 8 digits, padding with leading zeroes if necessary. Note that the underscore is there purely for readability.

Decimal Binary Hexadecimal
254 0b1111_1110 0xfe
101 0b0110_0101 0x65
214 0b1101_0110 0xd6

Integer Representations Solutions

Thanks to Andrew Benson for developing these materials!

back to the problems

p1 (integer sizes)

How many bytes do the following types take up on a common 64-bit computer such as the Myth machines?

  1. unsigned long: 8 bytes or 64 bits
  2. short: 2 bytes or 16 bits
  3. signed char: 1 byte or 8 bits

What C code could you write to determine the above?

Use sizeof on each type to get a size_t containing the number of bytes, then print it out. For example,

printf("%zu\n", sizeof(unsigned long));

p2 (integer ranges)

What is the range of integral values representable by each of the following types?

  1. unsigned long: [0, 264-1]
  2. short: This is by default signed! [-215, 215-1]
  3. signed char [-27, 27-1]

p3 (signedness)

Suppose Andrew writes 0b1111_1111 on the board. He assures you that this is a 8-bit integer. What value does it represent? (Hint: trick question)

It's necessary to know whether this is a signed or unsigned integer to answer. If the former, then it's -1, and if the latter, then it's 255.

p4 (two's complement)

  1. You are given 0b1110_1011, a signed char. Determine its decimal value.

This is a negative number. The complement is 0b00010100. After adding 1, this is 0b00010101. Converting this to decimal yields 21. Thus, the original value was -21.

  1. You are given 0b1110_1011, a unsigned char. Determine its decimal value.

We can just sum up powers of two since unsigned integers use regular binary. This is 128 + 64 + 32 + 8 + 2 + 1 = 235.

  1. You write the following code:
signed char x = -13;

What is the underlying bit pattern of the signed char?

The bit pattern for 13 is 0b0000_1101. The complement is 0b1111_0010. Adding 1 yields 0b1111_0011 which is our answer.

p5 (overflow)

Alpha, Bravo, and Charlie are trying to write a C expression for the floored average of two unsigned int's. (That is, the average rounded down to the nearest unsigned int.) What do you think about their proposals?

  1. Alpha: (x+y)/2

Doesn't work. x+y can overflow yielding a much smaller average than correct.

  1. Bravo: x/2 + y/2

Doesn't work. Integer division makes us lose precision. Try x = 1, y = 1.

  1. Charlie: x + (y-x)/2

Doesn't work. y-x can overflow yielding a much larger average than correct.

Integer Casting Solutions

back to the problems

p1 (identifying casts)

Determine what cast (implicit or explicit) is occurring, and from what type to what type.

  1. long x = (long)2; (Explicit cast of 2 from signed int to signed long.)

  2. long x = 2; (Implicit cast of 2 from signed int to signed long.)

  3. int x = 7U; (Implicit cast of 7U from unsigned int to signed int.)

  4. 3L > 5UL (Implicit cast of 3L from signed long to unsigned long.)

  5. 1 / 0U (Implicit cast of 1 from signed int to unsigned int.)

p2 (casts in comparisons)

Evaluate each of the following boolean expressions (to true or false). Make sure you understand why!

  1. -8 < 5 (true)
  2. -8 < 5U (false)
  3. -8U < 5U (false, identical situation to the second)
  4. -8 < (signed int) 5U (true, identical situation to the first)
  5. -8 < (unsigned int) 5 (false, identical situation to the second)

p3 (truncating casts)

Evaluate each of the following boolean expressions (to true or false). Make sure you understand why!

  1. (unsigned char) 256 > 1 (false, 0 > 1)
  2. (unsigned char) 257 > 1 (false, 1 > 1)
  3. (unsigned char) 258 > 1 (true, 2 > 1)

p4 (casts in arithmetic)

What is the value of c? Be careful of the effect of implicit casts.

int a = -3;
unsigned int b = 1U;
int c = (a + b) / 2;

a + b causes a to be casted to unsigned int. The casted a has a value of 232-3. The sum is 232-2, and after division (the 2 is casted to unsigned, though this has no net effect), is 231-1. It then gets casted back to signed int, but maintains its value since it's representable in the range of a signed int. The final value is thus 2147483647.

Note that the final value is not the expected (-3 + 1) / 2 = -2 / 2 = -1!