Assignment 1: DataLab (due on Tue, Sep 16, 2025 by 11:59pm)
Introduction
The purpose of this assignment is to become familiar with the bit-level representation of integer and floating-point numbers (and their operations). You’ll achieve this by solving a series of programming puzzles! Many of these puzzles are quite artificial, but you’ll find yourself thinking much more about bits while working your way through them.
You can assume 32-bit 2’s complement integers (int in C on x86-64) and 32-bit
IEEE 754 floating-point variables (float in C). Floating point variables are
passed to your functions as unsigned int (on which you operate using bitwise
and other integer operations).
Notably, problems on the manipulation of floating point variables allow you to
use a larger set of operations, including loops (for, while, do while),
conditional statements (if), all operators (including -, >, <) and
4-byte constants.
To solve the problems, you must know:
- 2’s complement and integer operations (negation, addition, subtraction, bitwise operations).
- Overflow conditions for addition and subtraction of signed integers.
- The bit-level format of
float(1 bit for sign, 8 bits for exponent in excess-127 format, 23 bits for fraction). - How to extract (and combine) sign/exponent/fraction fields using bitwise operations.
- The bit-level encoding of special values (positive/negative zero and infinity, NaN) and their behavior with respect to floating-point operations.
Logistics
This is an individual project. All handins are electronic. Clarifications and corrections will be posted on the course Piazza page.
Remember that:
- You are not allowed to search for help online!
- Any time you receive help from a TA/CP, you should acknowledge that in your code with a comment starting with the string “assistance from”.
- You are not allowed to ask other students for detailed help, show them your code, or discuss the specifics of the solution.
- Reconsideration requests must be made within one week of our release of grades for the assignment.
Be aware that you may be asked to explain your code to a member of our course staff using only what you have submitted: your comments in the code should be such that you can determine what your code does and why a few weeks later, if needed.
Handout Instructions
Similarly to the previous assignment, we will create a private GitHub repository for this assignment and share it with you. Be sure to clone the GitHub repository on the programming server.
The only file you will be modifying and turning in is bits.c,
although other files will help you, such as to find out what your
grade will be. The bits.c file contains a skeleton for each of the
programming puzzles. Your assignment is to complete each function
skeleton using only straight-line code for the integer puzzles (i.e.,
no loops or conditionals) and a limited number of C arithmetic
and logical operators. Specifically, you are only allowed to use the
following eight operators:
! ~ & ^ | + << >>
A few of the puzzles/functions may further restrict this list so read
the comments of each puzzle/function carefully. Also, you are not
allowed to use any constants longer than 8 bits. See the comments in
README.md for detailed rules and a discussion of the desired coding
style.
In contrast, floating-point puzzles allow you to use 4-byte constants, loops and conditionals (with any comparison operator).
The Puzzles
Integer Puzzles
int tmin()(1 point, 1 ops allowed): return the minimum 2’s complement integer.int bitAnd(int x, int y)(1 point, 4 ops allowed):x&yusing only~and|.int bitXor(int x, int y)(1 point, 7 ops allowed):x^yusing only~and&.int negate(int x)(1 point, 2 ops allowed): duplicate the effect of-xwithout using-.int isEqual(int x, int y)(2 points, 2 ops allowed): return1ifx == y, and0otherwise.int satAdd(int x, int y)(4 points, 20 ops allowed): returnx + yif it does not cause overflow; return the integer max or min in case of positive or negative overflow.int bitMatch(int x, int y)(1 points, 8 ops allowed): create mask indicating which bits inxmatch those inyusing only~and&.int fitsShort(int x)(1 points, 4 ops allowed): return 1 ifxcan be represented as a 16-bit, two’s complement integer.int rotateRight(int x, int n)(3 points, 10 ops allowed): rotatexto the right bynbits.int byteSwap(int x, int n, int m)(3 points, 17 ops allowed): swaps the $n$-th byte and the $m$-th byte.
Floating-Point Puzzles
unsigned floatAbsVal(unsigned uf)(2 points, 5 ops allowed): compute(f > 0.0)?(f):(-f)for floating point argumentf. Both the argument and result are passed asunsigned int’s, but they are to be interpreted as the bit-level representations of single-precision floating point values. When argument isNaN, return argument.unsigned floatScale2(unsigned uf)(4 points, 13 ops allowed): return the bit-level equivalent of2.0*f(as afloat) for the floating point argumentf. When argument isNaN, return argument.
Evaluation
Your score will be computed out of a maximum of 48 points including 24 correctness points and 24 performance points.
-
Correctness points. The puzzles have been given a number of correctness points between 1 and 4, such that their weighted sum totals to 24. We will evaluate your functions using the
btestprogram (described in the next section) to check for correctness. You will get correctness points for a puzzle if it passes all the tests performed bybtest. -
Performance points. Our main concern at this point in the course is that you can get the right answer; but you should also try to keep things as short and simple as you can. Furthermore, some puzzles can be solved by brute force, but we want you to be more clever. Thus, for each function we’ve established a maximum number of operators that you are allowed to use. You will receive 2 additional performance points for each correct function that satisfies the operator limit. You can use the
dlcprogram (described in the next section) to check if your program satisfies these limits.
Note that we will be running the grade program to do the grading (correctness
and performance points).
Autograding your work
We have included the following grading tools in the handout.
-
btestchecks the functional correctness of the functions inbits.c. Every time you modifybits.c, you should recompile it withmake btestand run it as./btestto see how many correctness points you would receive. You can run./btest -f funcNameto test only a specific function, or./btest -f funcName -1 123 -2 456to testfuncName(123, 456). You can ignore any warnings aboutbtest.c:528:9: warning: variable errors set but not used. -
dlcis a modified version of an ANSI C compiler from the MIT CILK group that you can use to check for compliance with the coding rules for each puzzle (allowed operators and maximum number of operations). You can run it as./dlc bits.c: the program runs silently unless it detects a problem, such as an illegal operator, too many operators, or non-straightline code in the integer puzzles. Run as./dlc -e bits.cto also print the number of operations used by each function. You can ignore any warnings about/usr/include/stdc-predef.h:1: Warning: Non-includable file <command-line> included from includable file. -
gradeusesbtestanddlcto compute correctness/performance points and produce your final score (the instructors will use this program to evaluate your solution). Run it as./grade.
Hand-In Instructions
You must commit and push your solution to GitHub. Assignment collection will be
automatic: right after the assignment deadline, our grading system will fetch
the most recent commit on the master branch of your repository.
Be sure to run ./grade and verify that your program passes not only the
functional tests, but also the performance tests. The grade you see from
./grade will be the grade you get.
If you want to use late days, make a push after the deadline: we will use the push date (not the commit date) to determine your late days.
Advice
- Do not include the
<stdio.h>header file in yourbits.cfile, as it confusesdlcand results in some non-intuitive error messages. You will still be able to useprintfin yourbits.cfile for debugging without including the<stdio.h>header, althoughgccwill print a warning that you can ignore. - The
dlcprogram enforces a stricter form of C declarations than is the case for C++, or that is enforced bygcc. In particular, any variable declaration must appear in a block before any statement that is not a declaration. For example, it will complain about the following code:int foo(int x) { int a = x; a *= 3; /* Statement that is not a declaration */ int b = a; /* ERROR: Declaration not allowed here */ } - Run the
gradeprogram! We’ll be running the same program to determine your grade. You want to make sure it will work when we run it.
Acknowledgements. This lab was developed by the authors of the course textbook and their staff. It has been customized for use by this course.