0% found this document useful (0 votes)
18 views

Project 1

Uploaded by

coucou
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Project 1

Uploaded by

coucou
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

CMSC 201, Fall 2024

Project 1: Bit Operations

Note: This lab can be tricky so do not wait till the end to complete it.
Check the due date in canvas.

This is a lab created by the authors of our textbook and adopted exactly as book instructions.

1 Introduction

The purpose of this assignment is to become more familiar with bit-level representations of integers and
floating-point numbers. You’ll do 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 in working your way through
them.

2 Logistics

This is an individual project. You may discuss the lab with other students as long as your solutions are your
own. All handins are electronic. Clarifications and corrections will be posted on the project page and
emailed on Canvas.
You can choose to make a study group of 3/4 students from your class, but each student must
code their final submission. The group is to make it easier to have a discussion on understanding
the project. Each student must write their own solution.

3 Handout Instructions

Start by copying datalab-handout.tar to a (protected) directory on a Linux machine in which you


plan to do your work.
If you have a folder named, project1, then first cd to project 1 then type

cp /home/shared/201/projects/project1/datalab-handout.tar .

(There is a . at the end to indicate your current path)

The project files are in datalab-handout.tar, to unzip the files type

tar xvf datalab-handout.tar

This will cause a number of files to be unpacked in the directory. The only file you will be modifying and
turning in is bits.c.
You must not make changes to any other files.
The bits.c file contains a skeleton for each of the 13 programming puzzles. Your assignment is to
complete each function skeleton using only straightline code for the integer puzzles (i.e., no loops or con-
ditionals) 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 functions further restrict this list. Also, you are not allowed to use any constants longer than
8 bits. See the comments in bits.c for detailed rules and a discussion of the desired coding style.
Read the README file in the folder for instructions on how to compile and test your files.

4 The Puzzles

This section describes the puzzles that you will be solving in bits.c.

4.1 Bit Manipulations

Table 1 describes a set of functions that manipulate and test sets of bits. The “Rating” field gives the
difficulty rating (the number of points) for the puzzle, and the “Max ops” field gives the maximum number
of operators you are allowed to use to implement each function. See the comments in bits.c for more
details on the desired behavior of the functions. You may also refer to the test functions in tests.c.
These are used as reference functions to express the correct behavior of your functions, although they don’t
satisfy the coding rules for your functions.

Your task is to complete these functions based on the requirement specified in the description. For example,
complete the bitXor so that it performs bit xor of x and y using only & and ~ operations. You can use up to
maximum of 14 operators.

Name Description Rating Max Ops


bitXor(x,y) x ˆ y using only & and ˜ 1 14
bitAnd(x,y) x & y using only ~ and | 1 8
logicalNeg(x) Implement the ! operator using all of the legal 4 12
operators except !
isNotEqual(x,n) Return 0 if x==y, and 1 otherwise 2 6
getByte(x,y) Extract byte n from word x 2 6
logicalShift(x,n) Shift x to the right by n, using a logical shift 3 20
bitMask(highbit,low Generate a mask containing all 1’s between 4 16
bit) highbit and lowbit (The right most bit is index
0)

Table 1: Bit-Level Manipulation Functions.


4.2 Two’s Complement Arithmetic

Table 2 describes a set of functions that make use of the two’s complement representation of integers.
Again, refer to the comments in bits.c and the reference versions in tests.c for more information.

Name Description Rating Max Ops


tmin() Most negative two’s complement integer 1 4
isPositive(x) Return 1 if x>0, otherwise return 0 2 8
isNegative(x) Return 1 if x<0, otherwise return 0 2 6
copyLSB(x) Set all bits of result to least significant 3 5
bit of x

Table 2: Arithmetic Functions

4.3 Floating-Point Operations

For this part of the assignment, you will implement some common single-precision floating-point opera-
tions. In this section, you are allowed to use standard control structures (conditionals, loops), and you may
use both int and unsigned data types, including arbitrary unsigned and integer constants. You may
not use any unions, structs, or arrays. Most significantly, you may not use any floating point data types,
operations, or constants. Instead, any floating-point operand will be passed to the function as having type
unsigned, and any returned floating-point value will be of type unsigned. Your code should perform
the bit manipulations that implement the specified floating point operations.
Table 3 describes a set of functions that operate on the bit-level representations of floating-point numbers.
Refer to the comments in bits.c and the reference versions in tests.c for more information.

Name Description Rating Max Ops


floatAbsVal(uf) Compute absolute value of floating point input x 4 10
floatIsEqual(uf,ug Compute f = = g for floating point arguments f 4 25
) and g

Table 3: Floating-Point Functions. Value f is the floating-point number having the same bit representation
as the unsigned integer uf.

Functions floatAbsVal and floatIsEqual must handle the full range of possible argument values,
including not-a-number (NaN) and infinity. The IEEE standard does not specify precisely how to handle
NaN’s, and the IA32 behavior is a bit obscure. We will follow a convention that for any function returning
a NaN value, it will return the one with bit representation 0x7FC00000.
The included program fshow helps you understand the structure of floating point numbers. To compile
fshow, switch to the handout directory and type:

> make

You can use fshow to see what an arbitrary pattern represents as a floating-point number:
> ./fshow 2080374784

Floating point value 2.658455992e+36


Bit Representation 0x7c000000, sign = 0, exponent = f8, fraction = 000000
Normalized. 1.0000000000 X 2ˆ(121)
You can also give fshow hexadecimal and floating point values, and it will decipher their bit structure.

5 Evaluation
Your score will be computed out of a maximum of 70 points based on the following distribution:

54 (27*2) Correctness points.


26 Performance points.
20 Solution explanation points.

Correctness points. The 13 puzzles you must solve have been given a difficulty rating between 1 and 4,
such that their weighted sum totals to 32. The correctness points is multiplied by 2 to make it 64. We will
evaluate your functions using the btest program, which is described in the next section. You will get
full credit for a puzzle if it passes all of the tests performed by btest, and no credit otherwise.
Performance points. Our main concern at this point in the course is that you can get the right answer.
However, we want to instill in you a sense of keeping things as short and simple as you can. Furthermore,
some of the 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 for each function. This limit
is very generous and is designed only to catch egregiously inefficient solutions. You will receive 1 points
for each correct function that satisfies the operator limit.
Solution explanation points. You must also explain your process of solving the puzzle using comments.
Your solutions should be as clean and straightforward as possible. Your comments should be informative,
but they need not be extensive. The goal is to show that you understand the essential “trick” to each solution
and you solved it with understanding– not to repeat the code in English. Which means if you just write xor
of the variable x with variable y only then you will not get full points, you might want to write xor of
variable x and y to set the different bits to 1 for the next step.
If anyone submits just the code without any explanation instructor has the right to ask the student to explain
their process. In the situation that student is not able to explain their code there may be suspicion of
plagiarism.
This is an individual work and any solution suspected of using AI for generating code or comments will be
inspected for suspicion of plagiarism.
Here is a example with workout to perform bitOr using ~ and & but not |, and some appropiate comments.
This question is not asked in the project.
/* Question:
* bitOr - x|y using only ~ and &
* Example: bitOr(6, 5) = 7
* Legal ops: ~ &
* Max ops: 8
* Rating: 1
*/
int bitOr(int x, int y) {
//Solution:
//We can think about solving it using De-morgans law which states ~(~p & ~q ) = p | q
//Checking this for 6 and 5, 0101 | 0110 = 0111, and ~(1010 & 1001) = ~(1000) = 0111
//It holds true for other values as well including negative values
int notX = ~x;
int notY = ~y;
return ~(notX & notY);
}
In this simple example, you could have also tried various combinations of ~ and & and explain it
accordingly for an acceptable comments. But for other complex problem it may not be suitable since you
cannot possible try everything to get the answer. But if you do not write any comments then it is not
acceptable as there will be doubt of plagiarism.

Autograding your work


Note:
I am using my scale for grading values which may not match the autograder score, but you can see
if your program is correct or not in the autograder.

We have included some autograding tools in the handout directory — btest, dlc, and driver.pl —
to help you check the correctness of your work.

• btest: This program checks the functional correctness of the functions in bits.c. To build
and use it, type the following two commands:

unix> make
unix> ./btest

Notice that you must rebuild btest each time you modify your bits.c file.
You’ll find it helpful to work through the functions one at a time, testing each one as you go. You
can use the -f flag to instruct btest to test only a single function:
unix> ./btest -f bitAnd

You can feed it specific function arguments using the option flags -1, -2, and -3:

unix> ./btest -f bitAnd -1 7 -2 0xf

Check the file README for documentation on running the btest program.
• dlc: This is 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. The typical usage is:

unix> ./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. Running with the -e switch:

unix> ./dlc -e bits.c

causes dlc to print counts of the number of operators used by each function. Type ./dlc -help
for a list of command line options.

6 Handin Instructions

Make sure that you keep a backup of your solutions outside of server in case of issues with server in future.

Handin only the bits.c file.

handin cmsc201 project1 bits.c


If you submit it multiple times, I will grade only the last submission.
Remember to check Style points and add proper comments as well. Also do not change any other files than bits.c

7 Some notes
• Don’t 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 may print a warning that you
can ignore.

• The dlc program enforces a stricter form of C declarations than is the case for C++ or that is
enforced by gcc. In particular, any declaration must appear in a block (what you enclose in curly
braces) 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
*/
}

• You may get some warnings as below which you can ignore
btest.c:334:23: warning: ‘arg_test_range’ may be used uninitialized [-Wmaybe-
uninitialized]
334 | if (arg_test_range[2] < 1)
| ~~~~~~~~~~~~~~^~~

• Do not forget to make it after every change you make, otherwise it will not be recompiled.
• The questions are not in the order of difficulty, check the table for their rating and you might want to
try the easier ones first.

• If working on bits.c and understanding the test case looks complex, it might be easier to test the
functions in a separate program with your defined values (or values from the comments) and check
it. Then copy to bits.c if it looks correct.

Examples from class:

#include <stdio.h>

/* Question:

* bitOr - x|y using only ~ and &

* Example: bitOr(6, 5) = 7

* Legal ops: ~ &

* Max ops: 8

* Rating: 1

*/

int bitOr(int x, int y) {

printf("%x\n",~x);

printf("%x\n",~y);

return 2;

//returns the lsb of a number

//Eg" lsb(6)=0, lsb(5)=1

int lsb(int x){

int lastBit = x & 0xF;

return lastBit;

//returns the lsb of a number

//Eg" msb(6)=0, msb(-5)=1

int msb(int x){

/*
to get the most bit I shifted it right 31 times since there are 32 bits, and then i anded it with 1 to make other
bits 0

*/

int rightMostBit = x >> 31;

int lastBit = rightMostBit & 0x1;

return lastBit ;

int main(void) {

printf("%x\n",msb(-6));

return 0;

You might also like