Bit Transfiguration
code Transfigure data with bit-level operations.
- Assign: Thursday, 9 February
- Checkpoint: aim to complete at least 5 puzzles by 11:59pm Thursday, 16 February
- Due: 11:59pm Tuesday, 21 February
- Collaboration: individual code assignment policy, as defined by the syllabus and honor code.
- Starter Code:
hg clone ssh://hg@bitbucket.org/cs240codetub/cs240-bits-owner
(Need help?) - Submit: Commit and push your final revision and double check. (Need help?)
- Relevant Reference:
- bitwise operations
- integer representation
- K&R 2.7, 2.9
CS 240 is a low-level systems course where the low-level system details matter. Some provided tools will not run elsewhere. Some solutions that work on other compilers may fail with ours (and vice versa). Do not waste time trying to use a different environment (Mac/Windows). Use a CS 240 computing environment.
Contents
- Overview
- Learn CS 240 Software Tools
- Setup
- Preparatory Exercises
- Tasks
- Puzzles
- Compiling and Testing
- Grading
- More Tools
Overview
This assignment requires you to solve a series of programming puzzles to become familiar with data representation at the bit level. Some puzzles may seem far removed from your previous programming experience, but bit manipulations like these are crucial for efficiency in essential applications such as cryptography, data compression, or encoding and decoding pictures, audio, video, and more. These puzzles will push you to think in new ways and internalize how computers deal with bit representations. Mind-twisters, enlightenment, and fun await!
Advice
This assignment is your first 240 code assignment. It is signficantly more challenging (and fun!) than the assignments that precede it.
Learn the tools. Before starting to write code for this assignment, learn the CS 240 software tools. You will use these tools repeatedly during this assignment and the rest of the course. If you are a Python programmer with no knowledge of Java or C, check out C for Python programmers.
Start early. Start this assignment soon after you submit the preceding assignment. This assignment will take considerably longer than the paper exercises we have done so far. Even if you are already comfortable with the bitwise operators, these puzzles are not easy. Allow plenty of time do some work, get stuck, sleep on it, and come back. Any recent CS 240 alum will confirm that we are serious about this!
Prepare and plan before you code. Complete the preparatory exercises. Try some pencil-and-paper or whiteboard hacking to design your solution before you start typing C.
Commit often. Each time you get a new function working (or even
just closer to working), hg commit
your work with Mercurial. Also
push your commits to your Bitbucket repository reasonably often. Then
if things go wrong later you can always recover your work.
Learn CS 240 Software Tools
For this assignment, you will learn to use a handful of programming tools that we will use repeatedly throughout the semester. You are not expected to know these already, but you are expected to learn them. Please do not hesitate to ask questions as you do. In some semesters we get more or less time to cover these during lab. Some learning and practice with these tools on your own time is necessary and beneficial in all semesters.
- Create a Bitbucket account using these steps if you have not yet.
- Complete the
lab tutorials
on the command line, the Emacs, and C.
- Complete the Linux tutorial section of lab using this additional documentation.
- Complete the Emacs tutorial section of lab using this additional documentation.
- Complete the C and bit puzzles section of lab using this additional documentation.
- Connect your Bitbucket account to your local account using these steps. Do this once on any CS Linux lab machine and once on your wx appliance if you have decided to use it.
- Read to understand the purpose of Mercurial and Bitbucket.
- Complete the Mercurial Solo Basics Tutorial.
Setup
Each student is provided with a Mercurial repository hosted on
Bitbucket. Your repository for this assignment is called
cs240-bits-owner
, where owner
is replaced with your Bitbucket
username. This repository contains starter code and is where you will
submit your work for the assignment.
To start, hg clone
your Bitbucket repository to your
local computer account.
- As you make changes, you will record them with
hg commit
and submit them (or make backups) to your Bitbucket repository withhg push
. The instructors will collect your work there. - If you are already comfortable with the Mercurial workflow from lab, note that the assignment manifest at the top of every assignment gives steps necessary to obtain starter code. (We purposelfully omit full instructions right here so you get used to finding them there.)
- The Solo Workflow summarized here or the full Mercural Tutorial will walk you through in more detail if you are not yet comfortable.
Your Beginner’s Bit Transfiguration Kit contains the following files, explained in later sections of this document:
bits.c
: you will edit this filebtest.c
,dlc
,driver.pl
: testing code and toolsMakefile
: recipes to compile testing code with themake
commandREADME
: documentation of testing tools- remaining files are adiitional support for testing
Preparatory Exercises
CS 240 code assignments include preparatory exercises. You do not need to submit answers to these exercises for grading, but you must complete them before starting the main assignment.
- You may ask questions on preparatory exercises at any time.
- You must complete the preparatory exercises (and show evidence) before asking code/debugging questions about the main assignment.
A. Learn your Tools
B. Bitwise Warmup
Examine the code below:
unsigned puzzle(unsigned x, unsigned y) {
unsigned result = 0;
for (unsigned i = 0; i < 32; i++){
if (y & (1 << i)) {
result = result + (x << i);
}
}
return result;
}
- Simulate this code on the (
x
,y
) pairs (2,3), (3,9), and (5,2). - Can you think of a better name for this function, describing what
it computes from
x
andy
(now how)?
C. Read the Instructions
Skim the rest of this document, as well as as the coding rules given
in bits.c
. To help with this tour, here are a few questions to answer.
- What command should you run to compile your code?
- What command should you run to test both correctness and compliance of your solutions?
- Are loops allowed?
- How many arguments does the
thirdBits
function take? What operators are allowed inthirdBits
?
Tasks
Your task is to solve the given bit puzzles and explain your solutions. The bits.c
file contains rules, specifications, and function templates for the programming puzzles. For each puzzle, you must:
- Implement the function according to the specification and coding rules.
- Explain in one or more comments why your solution works.
Implementation
All functions must obey the restrictive coding rules at the top of bits.c
. Read the rules carefully before starting – they are essential. The rules restrict you to performing only bit-level operations on data. The purpose of these restrictions is to force you to think about the data as bits. Due to the restrictions, your solutions may not be the simplest or most efficient way to accomplish the function’s goal, but the process of working out the solution should make the notion of data as bits completely clear.
For each individual function, a comment in bits.c
gives:
- a specification of the function’s behavior
- the set of operators allowed
- the maximum number of operations allowed
- a rough difficulty rating, from low (1) to high (4)1
Tests in test.c
include a reference implementation of the function that can also help understand expected behavior. The reference implementations completely ignore restrictions on allowed operations.
Tables below summarize the difficulty rating and description of each function.
The Testing section below describes how to evaluate compliance and correctness in your solutions.
Explanation
For each function, one or more comments must explain how and why your solution works.
Translating the series of operations into English comments does not suffice. Re-explaining the high-level specification of what the function computes does not suffice. Both of those explain what. Your comment must demonstrate clearly that you understand the link between these. How/why do the effects of the individual operations combine to implement the specification?
In some cases your comments may be shorter than your code. In some cases they may be longer.
Puzzles
The puzzles are summarized here and documented more precisely in bits.c
.
Raw Bitwise Functions
These functions do checks and manipulations on 32-bit values treated as bit vectors (i.e., they do not interpret the values as numbers).
Rating | Function Name | Description |
---|---|---|
1 | bitAnd | x & y using only ~ and | |
1 | bitXor | x ^ y using only ~ and & |
1 | thirdBits | return word with every third bit (starting from the LSB) set to 1 |
2 | getByte | Extract byte n from word x |
3 | logicalShift | logical shift x to the right by n |
4 | bang | Compute !x without using ! |
3 | conditional | x ? y : z |
Two’s Complement Functions
These functions do checks and manipulations of 32-bit 2’s-complement integer values.
Rating | Function Name | Description |
---|---|---|
2 | fitsBits | returns 1 if x can be represented as an n-bit, two's complement integer |
2 | sign | return 1 if positive, 0 if zero, and -1 if negative |
3 | addOK | Determine if x+y can be computed without overflow |
4 | isPower2 | returns 1 if x is a power of 2, and 0 otherwise |
Compiling and Testing
We have included a few tools to help you check your work.
To build (compile) your solutions and provided testing code, type the command make
. The make
command looks for a file called Makefile
that gives a recipe for how to compile a given executable so that you can avoid retyping long compilation commands each time you need to compile a new version. The Makefile
we provide (take a look) compiles your code with testing code and produces an executable file called btest
.
[Update Feb 16] If you experience errors like this:
bpw@finch: ~/240/starters/cs240-bits$ make
gcc -O -Wall -g -pedantic -Werror -lm -o btest bits.c btest.c decl.c tests.c
bits.c:1:1: error: C++ style comments are not allowed in ISO C90
bits.c:1:1: error: (this will be reported only once per input file)
...
Edit the file Makefile
in your repository. Replace the line:
CFLAGS = -O -Wall -g -pedantic -Werror
with
CFLAGS = -O -Wall -g -Werror
by removing -pedantic
.
The -pedantic
option helps detect errors earlier, but the lab
machines currently have an old version of the C compiler that is a
little too -pedantic
. Until we can update it, please follow the
above steps if you encounter the problem.
Correctness: btest
btest
is a program that checks the functional correctness of the code in bits.c
.
To run tests of your solutions, type the command ./btest
. This runs the executable file btest
, which tests the version of bits.c
that has been compiled. Every time you update bits.c
and want to run btest
, you must first run make
to compile btest
using the latest version of your code.
$ make
$ ./btest
You can use the -f
flag to instruct btest
to test only a single function. For example, to test only bitXor
, run:
$ ./btest -f bitXor
You can feed it specific function arguments using the option
flags -1
, -2
, and -3
. For example, to test bitXor(1,0xf)
, run:
$ ./btest -f bitXor -1 7 -2 0xf
Check the README
file for documentation on running the btest
program.
We may test your solution on inputs that btest does not check by default and we will check to see if your solutions follow the coding rules.
Coding Rules: dlc
dlc
is a modified C compiler that you can use to check for compliance with the coding rules for each puzzle. The typical usage is:
$ ./dlc bits.c
The program runs silently unless it detects a problem, such as an
illegal operator, too many operations, or non-straightline code in the
integer puzzles. Running with the -e
switch:
$ ./dlc -e bits.c
causes dlc
to print counts of the number of operations
used by each function. Type ./dlc -help
for a list of
command line options.
[Updated Feb 13] You may receive one warning from dlc
which you can safely ignore:
/usr/include/stdc-predef.h:1: Warning: Non-includable file <command-line> included from includable file /usr/include/stdc-predef.h.
Pay attention to other warnings and errors.
Autograde: driver.pl
The driver.pl
tool will automatically grade your solutions on correctness and performance using the dlc
and btest
tools.
Points are awarded only for working solutions. The difficulty rating determines the number of correctness points available for each puzzle. Each puzzle may receive up to 2 performance points, based on the number of operations used.
Run the autograder like this (part of the output on our sample solution is shown):
$ ./driver.pl
[ ... status messages omitted here ... ]
Correctness Results Perf Results
Points Rating Errors Points Ops Puzzle
1 1 0 2 4 bitAnd
1 1 0 2 7 bitXor
1 1 0 2 4 thirdBits
2 2 0 2 7 fitsBits
2 2 0 2 4 sign
2 2 0 2 3 getByte
3 3 0 2 6 logicalShift
3 3 0 2 9 addOK
4 4 0 2 6 bang
3 3 0 2 7 conditional
4 4 0 2 11 isPower2
Score = 48/48 [26/26 Corr + 22/22 Perf] (68 total operators)
Issues with undeclared variables? See Variable Declarations.
Grading
Submit your work by committing and pushing your latest work to your Bitbucket repository, as indicated in the assignment manifest.
Before submitting, disable any diagnostic printing you added in bits.c
.
Your grade will be derived as follows:
- Correctness and performance (72 points = 1.5 × autograder score):
- Correctness and performance of all puzzle solutions is graded.
- No credit is awarded unless the
driver.pl
autograder can compile and run your code.
- Succinct comments explaining why each puzzle solution works (28 points):
- Grading may consider explanations for a random subset of puzzles.
- Good comments describing incomplete or non-working solutions will receive credit.
Correct solutions that match or beat the operator count of the instructor’s solutions may result in prizes!
More Tools
Number Conversion
The ishow
tool lets you display integer representations and conversions. It takes hex or decimal input.
$ ./ishow 0x27
Hex = 0x00000027, Signed = 39, Unsigned = 39
Debugging
Do not include the stdio.h
header file in your
bits.c
file, as it confuses dlc and results in some non-intuitive
error messages. You will still be able to use printf in your bits.c
file for debugging without including the stdio.h
header, although gcc
will print a warning that you can
ignore.
Variable Declarations
The dlc
program enforces a stricter form of C
declarations than gcc
enforces. In particular, in a block (what you enclose in
curly braces) all your variable declarations must appear before any
statement that is not a declaration. For example, dlc
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 */
return b+2;
}
Instead, you must declare all your variables first, like this:
int foo(int x) {
int a = x;
int b;
a *= 3;
b = a;
return b+2
}
Number Notation
You may use decimal number notation (normal syntax, e.g., 87
) or
hexadecimal notation (0x57
). dlc
will NOT accept binary notation
(0b01010111
).
-
Different people have different opinions about which puzzles are more difficult. ↩