Vous êtes sur la page 1sur 17

ECE 150 Midterm Test

Term: Fall

Year: 2015

TOTAL MARKS: 100


This test is worth 10% of a students final grade for ECE 150.
Student Name: ______________________________________________________________
Signature: __________________________________________________________________
Student Identification Number: ________________________________

Course Abbreviation and Number:

ECE 150

Course Title:

Fundamentals of Programming

Section:

001

Instructor:

Alfred C. H. Yu

Date of Exam:

Thursday October 22, 2015

Exam Period Start time: 8:30 am

End time: 10:20 am

Duration of Exam:

1 hour 50 minutes

Number of Exam Pages: (includes cover page)


Exam Type: (select one)

Closed
Book

16

Special
Materials

Open
Book

Materials Allowed: (select one)


No additional materials are allowed.
Materials allowed are listed below:
One letter-sized note-sheet. These rules apply: (i) must be handwritten; (ii) may be
double-sided; (iii) must be an original copy, (iv) photocopies, printed materials,
scanned printouts, and non-handwritten note-sheets are not allowed.
General Exam Policies:

No electronic devices including no calculators.

State any assumptions clearly and whenever needed.

No questions are permitted during the test. If you are unsure about something, make an
assumption and write it down.

If you write the test in pen, you may appeal your test score in the event of discrepancy.
However, if you write the test in pencil, you may not appeal your test score except for
procedural errors related to incorrect totaling of marks from individual questions.

You are not allowed to leave the examination room in the first 1 hour of the test (i.e. before
9:30am) nor in the final 10 minutes of the test (i.e. after 10:10am).

ID Number: _________________________
Marking Scheme
Part

Question Type

Maximum Score

True or False

20

Short Answers

30

Long Questions

50

Total

100

1. True or False [20 Marks]


(+2 marks for each correct answer, 0 marks for each instance of no response,
1 mark for each incorrect answer)
FALSE

(a) The output of the following code snippet is x is 7; y is 3.


int x = 7;
int y = x ^ 3;
cout << "x is " << x << "; y is " << y;
y is set equal to the bitwise XOR between 7 and 3, whose binary form are
respectively 000000111 and 000000011. At a given bit position, bitwise
XOR would yield either: 0 (if both bits are 0 or 1); or 1 (if one of the two bits is
1). In this case, we have 0 for the rightmost and second rightmost bits, 1 for
the third rightmost bit, and 0 for all other bits. The result is 000000100 (the
number 4 in base 10). Therefore, the correct output should instead be x is 7;
y is 4

FALSE

(b) The following code snippet would yield the output phrase One-third.
float x = 1/3;
if (x == 0.333)
cout << "One-third";
else if (x == 0.667)
cout << "Two-third";
else
cout << "Can't tell what x is";
Although 0.333 is an approximation of 1/3, it is not exactly equal to the
floating-point representation of 1/3. Therefore, when the test expression is
evaluated in the first if statement, the outcome is false. Accordingly, itll fall to
the last else branch that outputs Cant tell what x is to the screen. As
mentioned in the class, it is dangerous to perform equality tests with floatingpoint numbers. Try to avoid doing this.

TRUE

(c) Assuming that the variable x is already defined, the following two C++
code snippets would both assign a value to the new variable y in the same way.
Snippet 1

int y = (x==5) ? x*5 : x+5;

Snippet 2

int y;
if (x==5)
y = x*5;
else
y = x+5;

Snippet 1 is an example where the ternary operator is used. What this does is
that it would check if x equals to 5; if yes, y = x*5, or else y = x+5. Such an
operation is the same as Snippet 2 that first defines the variable y and then
use an if-else statement to conditionally assign a value to y.

ECE 150, Section 001 Fall 2015

Page 2 of 17

ID Number: _________________________
FALSE

(d) A program would repeatedly check whether the current test expression is
false and enter an infinite loop by executing the following C++ statement:
while(0);
Contrary to the above statement, programs written in the C/C++ language
would execute statements in the while loop only if the test expression within
the brackets is true. In this case, the program would simply jump out of the
while loop after checking once and realizing that the test expression is not
true.

FALSE

(e) By sequentially performing the steps of fetch, decode, and execute, one
single CPU instruction cycle is sufficient to realize an infinite loop that
involves the evaluation of a test expression.
Although it is true that each CPU instruction cycle involves the general steps
of fetch, decode, and execute, it is simply not possible for a single instruction
cycle to realize the logical organization of an infinite loop. In general, the CPU
instruction set does not have a loop forever instruction, so it is not possible to
directly tell the computer to loop on an infinite basis. It is necessary to
construct an infinite while loop, but this would involve multiple instruction
cycles.

TRUE

(f) Given that the variables num1 and num2 exist beforehand, the value
assigned to the boolean variable isInRange would be the same in the
following two C++ code snippets.
Snippet 1

bool isInRange = !(num1 > 10 && num2 < 20);

Snippet 2

bool isInRange = num1 <= 10 || num2 >= 20;

For snippet 1, the boolean variable is false if num1 is greater than 10 AND if
num2 is less than 20. In other words, it is true if either: 1) num1 is less than or
equal to 10, or 2) num2 is greater than or equal to 20. This latter interpretation
is exactly the same as the test expression set forth in Snippet 2.
TRUE

(g) For the following C++ code snippet involving an array variable, the
resulting value stored in the variable sum is 6.
int data[6] = {6, 5, 4, 3, 2, 1};
int sum = data[3] + *(data+3);
The syntax data[3] would access the value stored in the memory address that
corresponds to the base address of data (i.e. where the first array element is
stored) plus 3 offset units (i.e. where the fourth element is stored). The same
operation is performed for the syntax *(data+3). Therefore, the result of sum
should be 3+3=6.

FALSE

(h) As mentioned repeatedly throughout the course, the most important


learning outcome of ECE 150 is for you to memorize all keywords related to
the C/C++ language, while the secondary learning outcome is to instruct
computers to carry out operational tasks using the C/C++ language.
Not at all! The fact is quite the contrary. ECE 150 is not about memorizing all
the keywords related to the C/C++ language. This is why you are allowed to
bring in a 1-page notesheet to help you jot down things that you think are
important to you during the test. In ECE 150, we emphasize a lot more on
helping you become proficient in instructing computers to carry out operational
tasks using the C/C++ language.

ECE 150, Section 001 Fall 2015

Page 3 of 17

ID Number: _________________________
TRUE

(i) The following C++ code snippet would output the text phrase Good
morning! to the screen, and this phrase would only be outputted once.
int count = 0;
do{
cout << "Good morning!" << endl;
count++;
} while (count++ == 0);
Since this is a do-while loop, the cout statement would be executed at least
once. The value of count would be 1 at the end of the first run of the do-while
loop. Subsequently, the test expression (x++ == 0) would be evaluated as
false since x is already equal to 1. Accordingly, the loop would not be repeated
for a second time, and the phrase Good morning! is only outputted once.

TRUE

(i) In the following C++ code snippet that seeks to output the multiplication
table, one of the 100 output text lines is 10x10=100.
for (int i=1; i<=10; i++)
for (int j=1; j<=10; j++)
cout << i << "x" << j << "=" << i*j << endl;
This is a nested for loop structure, and the inner loop would be executed 10
times for each value of i. Since the outer loop is iterated 10 times, and the
inner loop is also iterated 10 times for each outer loop value, the cout
statement would be executed 100 times. The text line 10x10=100 would
appear as the last output line of the nested loop when i is 10 and j is 10.

2. Short Answers [30 Marks]


Question A (6 marks in total)
We wish to design a computer program that can check whether an input character is a letter or
not. If it is indeed a letter, it would change its case either from: upper-case to lower-case, or
lower-case to upper-case. For your information, the ASCII values for a to z are in the range of
97 to 122, while those for A to Z are in the range of 65 to 90.
(i)

(3 marks) In one sentence each, please describe in words how you can:
1) Check if the input character is a letter or not
Set a test expression that would evaluate if the ASCII value of the character is either
between 65-90 or 97-122.

2) Transform an upper-case letter to a lower-case letter


Add the difference in ASCII value between a and A (i.e. 97-65 = 32) to the ASCII value
of the input character.

3) Change a lower-case letter to an upper-case letter


Subtract the difference in ASCII value between a and A (i.e. minus 32) to the ASCII
value of the input character.

ECE 150, Section 001 Fall 2015

Page 4 of 17

ID Number: _________________________
(ii)

(4 marks) Write a C++ code snippet that would achieve the three features described in (i).
The code should fit within the following location as indicated.
#include <iostream>
using namespace std;
int main(){
// Define a variable called letter, and ask user for input
char letter;
cin >> letter;
// If the input is invalid, simply terminate the program
if (cin.fail())
return -1;
// Swap the letter from upper to lower case,
// or from lower to upper case
// Also check whether the input character is a letter or not
char newLetter;
bool isLetter;
//
// YOUR CODE SNIPPET WILL BE PLACED HERE
//
// Output results to screen
if (isLetter){
cout << "The original letter is " << letter << endl;
cout << "The transformed letter is " << newLetter << endl;
}
else
cout << "The input character is not a letter." << endl;
return 0;
}

For this particular question, we did not assign marks to your code comments since we
have already asked you to explain your solution in words in part (i). Nevertheless, it is
always nice to document your code as you can see below.
// 1. Check if the input is a letter or not
isLetter = (letter>=65 && letter<=90) || (letter>=97 && letter<=122);
// 2. If the input is indeed a letter,
//
change its case from upper to lower or from lower to upper
if (isLetter){
// a) If the character is lower-case letter,
//
add the equivalent ASCII difference between 'A' and 'a'
//
to transform it to an upper-case letter
if(letter >= 65 && letter <= 90)
newLetter = letter + 32;
// b) On the other hand, if the character is upper-case letter,
//
add the equivalent ASCII difference between 'a' and 'A'
//
to transform it to a lower-case letter
else if(letter >= 97 && letter <= 122)
newLetter = letter - 32;
}

ECE 150, Section 001 Fall 2015

Page 5 of 17

ID Number: _________________________
Question B (7 marks in total)
A novice programmer wrote the following uncommented and poorly indented C++ program to
check whether some numbers are multiples of 4. Please help this programmer verify the
calculations and the program output.
#include <iostream>
using namespace std;
int main(){
int x[6]={1,-1,2,1,1};
int y[6];
for (int count=0; count<4; count++)
y[count] = ( x[count] + x[count+1] ) << 2;
y[4] = *(x+1) << 1;
y[5] = 0;
int count = 0;
while (count < 6){
if (y[count] % 4 == 1)
cout << "y[" << count << "] is a multiple of 4" << endl;
else
cout << "y[" << count << "] is NOT a multiple of 4" << endl;
count++; }
return 0; }

(i)

(4 marks) What is going to be the value of each array element in y before the while loop
is executed? Please show your work.
Note that left-shift by 2 bits is equivalent to multiplying by 22 (i.e. 4). Thus, for the first
four elements of y, its value is equal to:
y[0] = (x[0] + x[1]) 4 = 4(1 + (-1)) = 0
y[1] = (x[1] + x[2]) 4 = 4((-1)+2) = 4
y[2] = (x[2] + x[3]) 4 = 4(2 + 1) = 12
y[3] = (x[3] + x[4]) 4 = 4(1 + 1) = 8
On the other hand, y[4] first involves: 1) looking up the array element of x that
corresponds to base address plus 1 offset unit (i.e. x[1]), and 2) multiplying the result by
21 (i.e. 2).
y[4] = x[1] 2 = 2(-1) = -2
Lastly, y[5] is simply equal to 0.

(ii)

(3 marks) Following from the code written at the top of this page, what is the screen
output of this program? Is this output logically correct? If not, please point out the code
line that needs to be fixed, and give the correct version. Reminder: This program
supposedly shows on screen whether a certain number in the array is a multiple of 4.
The while loop checks whether the modulus of each array element, when divided by 4
is equal to one. Given the above values of y[count], we would have the following screen
outout:
y[0] is NOT a multiple of 4
y[1] is NOT a multiple of 4
y[2] is NOT a multiple of 4
y[3] is NOT a multiple of 4
y[4] is NOT a multiple of 4
y[5] is NOT a multiple of 4
Yes, there is a bug, because the numbers 0, 4, 8, 12 should be multiples of 4. The bug is
located in the test expression (y[count] % 4 == 1). It should be (y[count] % 4 == 0)
instead. If this issue is fixed, the program would give the correct output.

ECE 150, Section 001 Fall 2015

Page 6 of 17

ID Number: _________________________
Question C (8 marks in total)
For CPUs that are designed based on the RISC (Reduced Instruction Set Computing)
architecture, they are able to carry out the following instructions:

LD <memory location>,<register>
Load the value stored in memory location and copy it to register

SD <register>,<memory location>
Store the value stored in register and copy it to memory location

SUBi <register_a>,<integer>,<register_b>
Subtract integer from the value in register_a, and store the result in register_b

ADDi <register_a>,<integer>,<register_b>
Add integer to the value in register_a and store the result in register_b

JGEZ <register>,<line number>


Jump to line number (i.e. set the CPU program counter to line number) if the value
in register is greater than or equal to 0, and increment the program counter by 1
otherwise

JMP <line number>


Unconditionally jump to line number (i.e. set the CPU program counter to line
number)

Suppose we have the following set of instructions.


111:
112:
113:
114:
115:
116:
117:
118:

(i)

LD 486, R1
LD 563, R2
SUBi R1, 3, R3
JGEZ R3, 117
ADDi R1, 5, R2
JMP 118
ADDi R2, 10, R2
SD R2, 563

(4 marks) For the above sequence of instructions, please give a one-sentence response to
each of the following mini-questions:
1) After Instruction 114, under what circumstance would Instruction 115 be executed?
Instruction 115 would be processed if R1 minus 3 is less than zero (i.e. R1 minus 3 is
NOT greater than or equal to 0).

2) After Instruction 114, under what circumstance would Instruction 117 be executed?
Instruction 117 would be executed if R1 minus 3 is greater than or equal to zero (i.e. R1
minus 3 is NOT less than 0).

3) Instruction 118 would be executed immediately after either one of two possible
instructions have been executed. Which two instructions are we talking about?
It would either be executed after performing Instruction 116 or 117.

4) What kind of operation is carried out in Instructions 115 and 117?


Both are integer addition operations; Instruction 115 would add 5 to R1 and store the
result in R2, while Instruction 117 would add 10 to R2 and store the result in R2.

ECE 150, Section 001 Fall 2015

Page 7 of 17

ID Number: _________________________
(ii)

(4 marks) Based on the above, what is the equivalent C/C++ code snippet for the set of
instructions from 111 to 118? You can assume that memory address 486 is allocated to
the int variable x and that at address 563 is allocated to the int variable y.
The above CPU instruction set seems to correspond to the following C++ code snippet.
// Note: values of x and y can be anything,
//
and their value is implicitly loaded into the register
//
via instructions 111 and 112
if (x < 3)
// Instructions 113 and 114
y = x + 5;
// Instruction 115
// Instruction 116 would be executed at end of if branch
else
// Implicitly embedded Instruction 114
y += 10;
// Instruction 117
// Instruction 118 is implicitly embedded within the if statement

Question D (8 marks in total)


Alfred has developed a computer program to count the number of negative integers from a list of
numbers entered via keyboard (end of list is denoted by 0). For example, with the integer list 90
50 -13 -1 -5 13 -19 0, the output phrase Number of negative integer(s): 4 should be displayed
on the screen. Here is the C++ code that he wrote.
// Include screen I/O library and declare use of std namespace
#include <iostream>
using namespace std;
int main(){
// Define an input variable
int input;
// Define a variable for counting negative numbers; initialize it to 0
int numNegative = 0;
// Define a boolean variable to check whether to exit loop
bool exitFlag = false;
// Start the loop to read integers from the list
do{
// Get an integer from the list
cin >> input;
// Check whether to exit the loop
exitFlag = cin.fail() || input == 0;
// If exitFlag is off and the current integer is negative,
// increment the number of negative integers by 1
if (!exitFlag && input > 0){
numNegative++;
}
}while (exitFlag);
// Output analysis result to the screen
cout << "Number of negative integer(s): " << numNegative << endl;
return 0;
}

ECE 150, Section 001 Fall 2015

Page 8 of 17

ID Number: _________________________
(i)

(4 marks) Alfreds program is not working as expected. He keeps getting the output
Number of negative integer(s): 1 on the screen. He is now frustrated. Please point
out two problematic code lines in Alfreds program, and state the correct version of
that code line.
Although this piece of code is well documented, there are two bugs in the code:
1) The if statements test expression is problematic. In its present form, we are checking
for whether the exitFlag is off and whether the input is a positive number. We should
revise this test expression as:
if (!exitFlag && input < 0)
numNegative++;
2) The do-while loops test expression is also problematic. In its present form, we are
checking whether the exit flag is on, whereas it should really be checking whether the
exit flag is off. Thus, we should revise this test expression as:
do{
// Code operations
}while (!exitFlag);

(ii)

(4 marks) Alfred would like to add a minimum value tracking feature. Please propose
C++ code snippets accordingly to: 1) amend the variable definitions, 2) perform
minimum value tracking, and 3) amend the screen output. For each part, please state
clearly where that snippet should be placed in the revised program.

To add the minimum value tracking feature into the code, we need to make three
amendments:
1) Define a new variable listMin, and initialize it at 0. It should be placed before the start
of the do-while loop. Here is the C++ code line:
int listMin = 0;
2) Add an if statement within the do-while loop to check whether the current input is less
than the running value of listMin. If so, set input as the new listMin value. Ideally it should
be placed within the original if statement. Here is the C++ code snippet:
if (input < listMin)
listMin = input;
3) Add a cout statement after the first cout statement to display the listMin result to the
screen. Here is the C++ code snippet:
cout << "Minimum value: " << listMin << endl;

ECE 150, Section 001 Fall 2015

Page 9 of 17

ID Number: _________________________
3. Long Answer [50 Marks]
Question A (12 marks in total)
Instead of relying on the math.h library, we can actually create our own square root calculator.
From a computer programming standpoint, the algorithm involved is rather simple. Let us denote
a number as the variable num. The square root of this number can be iteratively approximated in
a few steps:
1st)

Make an initial estimate on the result, let us denote it as the variable sqrtEst

2nd) Divide num by sqrtEst


3rd) Average the result in (2) with sqrtEst
4th)

Use the result in (3) as the new estimate for sqrtEst, and repeat steps (2) and (3)

5th)

Repeat until the difference of sqrtEst for previous and current iterations are smaller
than a threshold

(i)

(2 marks) Let us work out some numbers to get a better understanding of the above
algorithm. Without using a calculator, fill in the following table entries for the relevant
quantities expressed in the above algorithm if num is 12 and sqrtEst is 2. Note that
(3.465)2 = 12.006225, so 3.465 is a close enough estimate of the square root of 12.

Iteration sqrtEst

(ii)

Average of

and sqrtEst

(12/2) = 6

(6+2)/2 = 3

(12/3) = 4

(4+3)/2 = 3.5

3.5

3.429

3.465

3.465

Stop. Close enough.

(4 marks) To reduce the number of iterations required in the above algorithm, it is


important to design a routine that can give an initial estimate of sqrtEst that is not too
far off. One solution is to set the initial value of sqrtEst as the smallest integer whose
squared value is larger to num. For such a solution, please describe in words the key steps
to find the smallest smallest integer with squared value larger than num.

1) Define a counter and initialize it as 1


2) Check if the squared value of current counter value is smaller than number of interest
a. If yes, increment the counter by 1, and repeat Step (2)
b. If not, the initial value of sqrtEst should be set equal to current counter value

ECE 150, Section 001 Fall 2015

Page 10 of 17

ID Number: _________________________
(iii)

(6 marks) Using the information in (i) and (ii), formulate a C++ code snippet to
approximate the square root of a number. Your code snippet must fit within the box as
indicated in the following C/C++ program:
#include <iostream>
using namespace std;
int main(){
// Define the variable for number, and get input from user
double num;
cin >> num;
// Define the threshold for square root estimation accuracy
double thr = 0.001;
// Define the variable for square root estimate
double sqrtEst;
//
// YOUR CODE SNIPPET WILL BE PLACED HERE
//
// Output the result
cout << "The square root estimate of " << num << " is "
<< sqrtEst << endl;
return 0;
}

Reminder: Please remember to include one line of code comment for every C++
statement you write (2 out of 5 marks will be given based on clarity of comments).

// PART ONE
// Coarse search for initial value of sqrtEst
// Define a counter (should be of double type to avoid data type
// discrepancy)
double count = 1.0;
// While squared value of count is smaller than the number,
// increment count by 1.0
while (count*count < num)
count += 1.0;
// Set initial value of sqrtEst as the current counter value
sqrtEst = count;
// PART TWO
// Fine search for square root estimate
// Define a squared variable
double squared = sqrtEst*sqrtEst;
// While the difference between squared and number is greater than
// threshold magnitude,update sqrtEst based on the prescribed algorithm
while ((squared - num) > thr || (squared - num) < -thr){
// 1. Calculate the new sqrtEst value as the average between
//
(num/sqrtEst) and sqrtEst
sqrtEst = ( num/sqrtEst + sqrtEst )/2;
// 2. Calculate the new squared value
squared = sqrtEst*sqrtEst;
}

ECE 150, Section 001 Fall 2015

Page 11 of 17

ID Number: _________________________
Question B (18 marks in total)
In Assignments 3 and 4, we have designed programs for single-bit parity checks and three-bit
parity checks. Let us now try to develop a two-bit parity check. The concept is very much similar
as before.
In this version of parity checking, we would set the left parity bit to be equal to the XOR of the
left bits in all bit pairs. Similarly, the right parity bit would be set equal to the XOR of the right
bits in all bit pairs.
(i)

(2 marks) Suppose we have four pairs of bits, 01, 11, 10, 11. What would be the value of
the two parity bits for this case? Please show your work.
Input for left parity bit calculation: 0, 1, 1, 1
Left parity bit = [(0 XOR 1) XOR 1] XOR 1
= [1 XOR 1] XOR 1
= 0 XOR 1
=1
o

Note that an XOR operation would yield 1 only if one of the two bits is 1, and it
would yield 0 if both bits are 0 or 1

Input for right parity bit calculation: 1, 1, 0, 1


Right parity bit = [(1 XOR 1) XOR 0] XOR 1
= [0 XOR 0] XOR 1
= 0 XOR 1
=1

(ii)

(3 marks) We have the following code template that involves the use of arrays for the
two-bit parity calculation.
#include <iostream>
using namespace std;
int main(){
// Define input in array format
int size = 10;
int data[size] = {0,1,1,1,1,0,1,1};
// Define an array two-bit parity check
int parity[2];
//
// YOUR CODE SNIPPET WILL BE PLACED HERE
//
// Display the final result
cout << parity[0] << parity[1] << endl;
return 0;
}

Based on this array data format, please describe in words the key steps involved in
performing the two-bit parity check operation as described at the beginning of this
question.
1) Initialize the values of both entries in the parity array to 0
2) Set a for-loop to count from 0 to (size-1), and incremented by two. For each iteration,
do the following:
i. Update the left parity bit, parity[0], as the bitwise XOR between: 1) the value
of data at current count index, and 2) the current value of parity[0]
ii. Update the right parity bit, parity[1], as the bitwise XOR between: 1) the value
of data at (current count index + 1), and 2) the current value of parity[1]

ECE 150, Section 001 Fall 2015

Page 12 of 17

ID Number: _________________________
(iii)

(3 marks) For the procedure that you have described in words in (ii), please formulate a
C++ code snippet that would serve the purpose of deriving the two parity bits for the
above array-based input format.
// Initialize parity bits to 0
parity[0] = parity[1] = 0;
// Define a for loop to stepwise calculate XOR
// for the current and next bit pair
for (int k=0; k <= size-1; k += 2){
// 1. Update the left parity bit
parity[0] ^= data[k];
// 2. Update the right parity bit
parity[1] ^= data[k+1];
}

(iv)

(2 marks) Let us try to do away with the use of arrays. We can actually use an unsigned
integer variable called data to represent all the bits, and then perform a series of mod-10
operations to extract each bit on a bit-by-bit basis, starting from the rightmost bit.
We can work out some numbers here. For the example in (i), the four bit pairs are 01, 11,
10, 11. The corresponding value of data is then 1111011 (only 7 digits; 8th digit is
implicitly assumed to be the leftmost zero). Fill in the following table entries based on the
operation listed in the table header.

(v)

Iteration

Data

Current Bit
(Data % 10)

Data /= 10;

1111011

111101

111101

11110

11110

1111

1111

111

111

11

11

Stop. End of Routine.

(3 marks) If we are not using arrays, we have the following code template instead. Please
describe in words the key steps involved in performing the two-bit parity check operation
as described at the beginning of this question. Note: You may not introduce the use of
arrays in your solution.
#include <iostream>
using namespace std;
int main(){
// Define input as an unsigned integer variable
unsigned int data = 1111011;
// NOTE: Input value only has 7 digits;
// 8th digit is implicitly assumed to be zero
// Define the left and right parity bits
unsigned int pLeft, pRight;
//
// YOUR CODE SNIPPET WILL BE PLACED HERE
//
// Display the final result
cout << pLeft << pRight << endl;
return 0;
}

ECE 150, Section 001 Fall 2015

Page 13 of 17

ID Number: _________________________

1) Initialize the values of both parity bits to 0


2) Define a bit position tracker variable, and initialize it to equal to the right bit position
3) Iteratively extract each bit as the modulus of data divided by 10. For each bit
extracted, do one of the following two:
a. If bit position tracker signifies left bit, update the left parity bit as the bitwise
XOR between: 1) the current bit extracted, and 2) the current value of left
parity bit
b. If bit position tracker signifies right bit, update the right parity bit as the bitwise
XOR between: 1) the current bit extracted, and 2) the current value of right
parity bit
4) Update the bit position tracker such that it will be processing the other parity bit
position in the next iteration
5) Find the quotient of data divided by 10, so that the next bit can be extracted
6) Repeat Steps (3), (4), and (5) until quotient is zero

(vi)

(5 marks) For the procedure that you have described in words in (v), please formulate a
C++ code snippet that would serve the purpose of deriving the two parity bits for the
above non-array input format. Once again, you may not introduce the use of arrays in
your solution.
Reminder: Please remember to include one line of code comment for every C++
statement you write (2 out of 5 marks will be given based on clarity of comments).
// Initialize parity bits to 0
pLeft = pRight = 0;
// Define a quotient variable for iterative mod-10 operations
// and initialize it to the series of bits
unsigned int quotient = data;
// Define a boolean variable for determining if
// current bit position is right bit
//
NOTE: Operation starts from the right bit,
//
so it is initialized to true
bool rightBitPos = true;
// Progressively extract each bit and update one of the two parity bits
while(quotient > 0) {
// 1. Derive the current bit as the modulus of
//
"current quotient divided by 10"
unsigned int currBit = quotient % 10;
// 2. Update the parity bit in the current bit counter position
if (rightBitPos){
// a. Update the right parity bit through a bitwise XOR
pRight ^= currBit;
// b. Change the rightBitPos checker to false
rightBitPos = false;
}
else{
// a. Update the left parity bit through a bitwise XOR
pLeft ^= currBit;
// b. Change the rightBitPos checker to true
rightBitPos = true;
}
// 3. Move to the next bit by dividing the current quotient by 10
quotient /= 10;
}

ECE 150, Section 001 Fall 2015

Page 14 of 17

ID Number: _________________________
Question C (20 marks in total)
We would like to draw a hollow diamond shape on a command-line console screen by
algorithmically using cout statements to output asterisks on a character-by-character and line-byline basis on a 2D grid.
Let us assume that the 2D grid is of odd dimensions, whose value is stored using the variable
name size. For example, if size is assigned the value of 7, the hollow diamond shape would
look as follows:

*
*

*
*

*
*

*
*

(i)

(4 marks) Assuming that the value assigned to size is a valid positive odd integer
greater than 1, we can define a new variable called midpoint and assign it the value
(size+1)/2. For the following lines in the 2D grid, please describe where the
asterisk(s) are positioned in terms of size and midpoint:
Line number

Where the asterisk(s) are positioned

midpoint pixel

2 to midpoint

(i) First asterisk appears at one pixel earlier than


previous line (midpoint lineCount + 1)
(ii) Second asterisk appears at one pixel later than the
previous line (midpoint + lineCount 1)

midpoint+1 to size-1

(i) First asterisk appears at one pixel later than


previous line (lineCount midpoint + 1)
(ii) Second asterisk appears at one pixel earlier than
the previous line (size (lineCount midpoint) )

size

(ii)

midpoint pixel

(2 marks) Based on the above asterisk position trends, please describe in words the key
steps involved in drawing the asterisk on the first and last lines of the hollow diamond.
1) Output blank space from Pixel 1 to Pixel (midpoint-1)
2) Output an asterisk
3) Output a line return

ECE 150, Section 001 Fall 2015

Page 15 of 17

ID Number: _________________________
(iii)

(3 marks) Please describe in words the key steps involved in drawing the two asterisks on
Lines 2 to midpoint of the hollow diamond.
Set a for-loop to count from 2 to midpoint. For the current line, do the following:
1) Calculate first asterisk position as (midpoint-lineCount+1) and second asterisk
position as (midpoint+lineCount-1)
2) Output blank space from Pixel 1 to Pixel (firstAsteriskPos-1)
3) Output an asterisk
4) Output blank space from Pixels (firstAsteriskPos+1) to (secondAsteriskPos-1)
5) Output an asterisk
6) Output a line return

(iv)

(3 marks) Please describe in words the key steps involved in drawing the two asterisks on
Lines midpoint+1 to size-1 of the hollow diamond.

Set a for-loop to count from midpoint+1 to size-1. For the current line, do the following:
1) Calculate first asterisk position as (lineCount-midpoint+1) and second asterisk
position as [size-(lineCount-midpoint)]
2) Output blank space from Pixel 1 to Pixel (firstAsteriskPos)
3) Output an asterisk
4) Output blank space from Pixels (firstAsteriskPos+1) to (secondAsteriskPos-1)
5) Output an asterisk
6) Output a line return

(v)

(8 marks) Using the information in (i), (ii), (iii), and (iv), formulate a C++ code snippet to
draw a hollow diamond on a character-by-character and line-by-line basis on a 2D grid.
Your code snippet must fit within the for-loop as indicated in the following C/C++
program:
#include <iostream>
using namespace std;
int main(){
// Define a variable called size, and ask user for grid dimension
int size;
cin >> size;
// If the input is invalid, simply terminate the program
if (cin.fail() || size <= 1 || size%2 == 0)
exit(1);
// Define a variable called midpoint
int midpoint = (size+1)/2;
// For-loop to iterate on a line-by-line basis
for (int L = 1; L <= size; L++)
{
//
// YOUR CODE SNIPPET WILL BE PLACED HERE
//
}
return 0;
}

ECE 150, Section 001 Fall 2015

Page 16 of 17

ID Number: _________________________
Continuation of Long Answers, Question C, Part (xi)
Note that the for-loop iterates from the first line to the last line of the 2D grid. You must
design your code snippet based on this looping condition, and it cannot be changed.
Reminder: Please remember to include one line of code comment for every C++
statement you write (3 out of 8 marks will be given based on clarity of comments).
// If current line is first or last line, simply output one asterisk
if (L == 1 || L == size){
// 1. Blank space from Pixels 1 to midpoint-1
for (int P=1; P <= midpoint-1; P++)
cout << " ";
// 2. Asterisk, followed by line return
cout << "*" << endl;
}
// If current line is between first or last line, output two asterisks
else{
// 1. Define variables for the 1st and 2nd asterisk positions
int firstAsterPos, secondAsterPos;
// 2. Check if current line is in the upper half of the diamond.
if (L <= midpoint){
// If yes:
// a. First asterisk should be at Pixel (midpoint-L+1)
firstAsterPos = midpoint-L+1;
// b. Second asterisk should be at Pixel (midpoint+L-1)
secondAsterPos = midpoint+L-1;
}
// else, the current line is in the bottom half of the diamond...
else{
// a. First asterisk should be at Pixel (L-midpoint+1)
firstAsterPos = L-midpoint+1;
// b. Second asterisk should be at Pixel [size-(L-midpoint)]
secondAsterPos = size-(L-midpoint);
}
// 3. Blank space from Pixel 1 to Pixel (firstAsterPos-1)
for (int P = 1; P <= firstAsterPos-1; P++)
cout << " ";
// 4. Asterisk at Pixel (firstAsterPos)
cout << "*";
// 5. Blank space from Pixels (firstAsterPos+1) to (secondAsterPos-1)
for (int P = firstAsterPos+1; P <= secondAsterPos-1; P++)
cout << " ";
// 6. Asterisk at Pixel (secondAsterPos), followed by line return
cout << "*" << endl;
}

ECE 150, Section 001 Fall 2015

Page 17 of 17

Vous aimerez peut-être aussi