CS61C, Summer 2010
Due Tuesday, July 13, 2010 @ 11:59pm
Copy the contents of ~cs61c/hw/05 to a suitable location in your home directory.
cp -r ~cs61c/hw/05 ~/hw5
Submit your solution by creating a directory named hw5 that contains the file fp.c. (Note that capitalization matters in file names; the submission program will not accept your submission if your file names differ at all from those specified.) From within that directory, type "submit hw5". This is not a partnership assignment; hand in your own work.
In this first part you will be writing the C function:
void sprint_float (char *outbuf, uint64_t input, int exp_bits, int mant_bits)
The function should write to
outbuf the string
input, interpreted as a float according to the
exp_bits refers to the number bits that should be
used for the
exponent field of the float, and
mant_bits refers to the number
of bits to be used for the mantissa of the float. There is also a single sign bit, so
the total number of bits in the float (starting from the least
significant bit) is
1 + exp_bits + mant_bits.
Since the size of the exponent field
we must also adjust the built-in bias. This generalizes to
These parameters allow for a great deal of flexibility not only adjusting the expressive power of the float, but also the tradeoff between range and accuracy.
exp_bits = 4, mant_bits = 5
- = Unused, S = Sign bit, E = Exponent, M = Mantissa (Significand)
Put your code in the framework in fp.c.
Test code is provided in test.fp.c.
You can compile and execute your code under the test bench by
Recall that uint64_t is the C99 64-bit int type.
You may assume that
outbuf already has enough space
allocated to hold your output. The quantity
1 + exp_bits + mant_bits will be some value <=64, with both
mant_bits >=1 (i.e. there is always at least
1 exponent bit and 1 mantissa bit, and the total number of bits in the float, including the sign bit,
will never exceed 64). Note that this implies that we
could potentially deal
with a float 3 bits wide, with one bit for each of S, E, and M. Such a
not have any room to hold regular (normalized) float values!
Print it to
outbuf according the format specified below:
1.ddd...dis the mantissa represented in binary (note the leading 1),
Estands for Exponent (where the right side is the power of 2 to multiply the mantissa by; recall scientific notation), and
xxis the (unbiased) exponent in binary. If the mantissa is 1.0, print out
1.0Exxxx...xDo not have any leading 0's on the exponent or trailing 0's on the mantissa.
mmmmis the whole number part of the float and
ddddis the fractional part. Do not have trailing or leading zeroes. In other words, do not print any extra zeros to the left of the whole number part, or to the right of the fractional part. If the fractional part is 0, print the decimal point followed by a single 0 (ie 1101.0 and not 1101). If the whole number part is 0 (the absolute value of the number is <1), you should start with '0.' (0.001101 and not .001101). See examples below.
The following table lists all the floating point possibilities ("maximal" refers to an exponent of all 1's):
|Object Represented||What you must write into the buffer|
|0||nonzero||? denormalized number||[-]denorm|
|nonzero, non-maximal||anything||? normalized number||[-]mantissa_in_binaryE[-]exponent_in_binary
according to rules above
|maximal||nonzero||NaN (Not a Number)||[-]NaN|
Sample cases (make sure you understand each of these before you start coding!):
||What gets printed to buffer|
|0x fff0, e=5, m=10,||-NaN|
|0x 6, e=2, m=1||infinity|
|0x 0000 0001 0000 0000, e=30, m=33||denorm|
|0b 11 0011, e=3, m=2||-11.1|
|0x 3455 4340, e=8, m=23 (standard float)||1.10101010100001101E-10111|
|0b 111 0110 1010, e=4, m=6||-1101010.0|
Now that we've familiarized ourselves with configurable float formats, we are ready to perform some basic analysis. In fp.c, complete the function:
int can_represent (int exp_bits, int mant_bits, int target)
The function should return 1 if the float specified by
mant_bits can precisely represent the integer
Hint: Think about the binary representation of
mant_bitswill take on the same range of values as in part 1.
targetmay be any signed integer.