CS61C Summer 2008 Midterm Grading Standard ############################################################## Question 1: Part a) 1/3 of a point for each incorrect or empty entry in the table. No partial credit offered. 4 points total. Part b) 1 point for each empty entry in the table. 4 points total. Lower right box 0.5 pts for "-0x7FFFF". This is for confusing that the answer was the bit representation. ############################################################## ############################################################## Question 2: Part a) 1 point for each scheme circled/not circled correctly. 3 points total. 0.5 points if the work for each scheme was correct, but the answer was incorrect. This is for cases where the student accidentally did the work correctly, but circled schemes that succeeded rather than failed. Part b) 1 point each, no partial credit. 4 points total. Part c) 1 point each, no partial credit. 3 points total. ############################################################## ############################################################## Question 3: 2 points each. 12 points total. Partial credit offered for all. Box 1) 1 point for correct bit pattern "1.111111111111" for identifying the correct significand bit pattern. 1 point for correct exponent "66" for identifying the correct unbiased exponent. Box 2) 1 point for exponent off by one, which is common in accidentally miscounting the number of bits to move the binary point. Box 3) 1 point for getting everything right but the sign. This is for correct work on the other fields. 1 point for rounding incorrectly. This is for correct work on the other fields. Box 4) 1 point for off by one. This is for accidentally counting both positive and negative zero. Box 5) 1.5 points for giving only one (either positive or negative) sets of denorms. This is because all that was missing was the +/- (so not realizing it was *all* denorms). 0.5 points for giving just the most negative denorm and the most positive denorm to define the range. This is because it is missing two needed values (the negative denorm of least magnitude and the smallest positive denorm); and it also includes +/- Zero (which are not denorms) and all the values between the smallest denorms and Zero. Box 6) 1.5 points for not including half of the NaNs. This is for simply not realizing that both + and - NaNs are NaNs. 1 points for off by one. This is for multiplying incorrectly, or for failing to take into account both +/- infinity, as well as a general math error. ############################################################## ############################################################## Question 4: 12 points total. BEQ) 3 points total. 1 point for correct immediate. This is for knowing how to calculate a branch immediate. 1 point for not trying to expand/rewrite (realizing that this is already TAL). 1 point for correct translation of specified TAL to Machine Language. ADDIU) 5.5 points total. 1 point for using $at 1 point for using lui/ori (or some other combination that performs same as addiu), for realizing that the immediate makes the given addiu MAL and not TAL. 1 point for using a combination that *can not* trigger overflow, for realizing that the expansion of a MAL instruction that can not trigger overflow can also not trigger overflow. 1 point for correct immediates to lui/ori (or whatever equivalent used), for knowing that immediates can be only 16 bits. 0.5 points for each correct translation to machine language. 1.5 points total for this. J) 3.5 points total 1 point for not expanding (realizing that this is already TAL) 1 point for correct translation to Machine Language. For this instruction this includes just the correct opcode, size of immediate field, and order of fields. 1.5 points for calculating the correct jump immediate. Partial Credit: 1 point for getting an incorrect immediate by using the correct method on the incorrect binary representation of the destination address. ############################################################## ############################################################## Question 5: The goal of this question was to test whether you knew how to iterate over C strings properly as well as iterating over pointers to structs. A secondary aspect of this problem was avoiding memory leaks, which is why we allowed you to add to the pocket_t struct and to add_pocket(). We did not take off points for anything irrelevant you added to pocket_t or add_herb. STRUCT DEFINITION - pocket_t -- 2 points total The answers were char *herb; struct pocket *next; You have to use struct pocket because the typedef won't go through yet. Each of these blanks were 1 point each. If you did struct pocket_t* or just pocket_t* instead, you got half credit. If you messed up struct pocket as well as realizing it's a pointer, you lost the whole point. ITERATING OVER HERB - i.e. healing completely -- 6 points total * -6 for ignoring herb string altogether ex: adding hp property to the struct * -4 not treating as string (supersedes rest) * for not moving to next character somehow - 2 points -2 for eating entire herb at once This is for not checking hp after each character, so herbs are never partially eaten. -2 for not leaving behind state of last eaten If an herb was partially eaten, you needed to leave something inside the pocket_t or herb itself to know where to start again. A local variable in heal() is not enough. -1 for not indexing array properly -1 for not incrementing index properly * adds herb's value to hp correctly - 1 point * common error was to add the pointer as the hp, not the characters within * -1/2 for using atoi - atoi is int==>char, not char==>int * not exceeding max_hp - 1 point * -1/2 if you don't actually reach full health Several students stopped if they reached a character that would put the entity over full health. The entity should still eat that character, but make sure to cap the hp at max_hp. * stopping correctly when you run out of characters - 1 point ex: herb == NULL, rather than *herb == NULL ex: using || of characters left + pockets left instead of && in loop stop condition ex: some other error with stopping correctly ITERATING OVER BELT (struct pointers) -- 8 points total * swapping pointers to advance pockets - 3 points -1 If you swap correctly, but don't change *belt_handle. The entity will have an incorrect pointer to the front of the belt then. -1 If you mix up the order of swapping -2 for interleaving frees and swap incorrectly This includes if you left out frees entirely. Part of the complexity in this problem is making sure you don't free too early, but also making sure you have pointers to things you need to free -2 for trying ++ on a pocket pointer * freeing old pocket correctly - 4 points * need to free both herb and pocket -4 for forgetting both -2 for forgetting struct -2 for forgetting herb -2 premature frees (if rest is correct) -1 for not considering problem of freeing in middle of string -1/2 for considering it, but bungling it somehow You can't call free on anything but the return value of a call to malloc. So if you increment the char* for herb so that you are in the middle of a string, that is no longer freeable. There were several ways of solving this and they are discusssed below. -1 Off for incorrect order of frees freeing struct before herb, because you no longer have the herb pointer after freeing the struct * stopping correctly - running out of pockets - 1 ex: using || of characters left + pockets left instead of && in loop stop condition MISC errors premature returns -.5 Some of your solutions would return too early given a certain situation. Because you had most of the logic, we gave you most of the points. These were marked as "control flow corner cases". strlen is not arraylen, -.5 Several students misused strlen, which does NOT include the '\0' when counting the number of characters in a string. one mistake with dereferencing belt_handle, -1/2 more than one mistake with belt_handle is conceptual -1 This reflects a misunderstanding of pointers and handles rather than a careless mistake with *'s. We did not take off for doing *belt_handle->herb, which is incorrect. The -> has higher precedence than *, so you need to use parens and get (*belt_handle)->herb. There were a few solutions that had a memory leak because they malloc-ed space that they initialized a pointer to point to, but immediately changed that pointer to point somewhere else. Remember! You can declare a pointer without having it point to something, as long as you remember to initialize it to a valid address of something existing or something newly allocated. INTERESTING SOLUTIONS Several students tried (successfully) a recursive approach, which we thought was interesting. It's usually not a standard way to program in C because of issue with stack growth, but a problem with linked lists always lends itself naturally to a recursive solution. The most creativity came up when dealing with how to store a pointer to the beginning of the herb so that you don't free in the middle, which is illegal. * The easiest way to do this was to add an extra pointer to store the front to pocket_t, and just free this at the end instead. * Another easy way is to add an index variable to the pocket_t and increment this instead of the char* itself. Then you can just free from the char*. * You didn't have to add anything to the pocket_t if you used strlen to find the end of the string each time, and as you ate characters, replaced them with '\0'. This way you store the state of where you last ate in the string itself, and never move char *herb off the front. This is why we allowed eating the herb in either direction. * You also didn't have to add anything to the pocket_t if you used some sort of "shift the contents of the string over 1 spot left each time" method. This could be done with strcpy (which might be unsafe because it could copy blocks at a time, but we still accepted it), a manual loop copying one character at a time, or even malloc-ing a new string, copying everything over but the character you just ate, and free-ing the old one. ############################################################## ############################################################## Question 6: Part a) 11 points total. Argument List: -0.5 for no return type since the function needs to return a value. -0.5 for only one argument in argument list, since the function takes two arguments. -0.5 for declaring the second argument as uint16_t. It should be unsigned, but it must be at least 32 bits. -1 for declaring the second argument as a signed type (if it is not later cast to an unsigned type when right shifting). In order for the C code to be equivalent to the given MIPS code, it *must* perform a shift-right logical which requires the second argument to be either declared to cast to unsigned. We are aware that the function will work even if it performs a shift-right arithmetic, but then it would not be equivalent to the given MIPS code. This was to test to ensure that the student knows how to get C to perform a shift-right logical. NOTE: There was an incorrect points deduction for declaring the second argument as just "unsigned". If you had 0.5 points deducted for this, inform a TA immediately. That half a point will be given back. Function (Minor Deductions): -1 for not shifting the second argument to the right, since this prevents each four bits from being accessed. -1 for not looping correctly/stopping incorrectly. -1 for shifting or multiplying the value used for the array offset (if you used pointer arithmetic/array notation). C does this for us when using pointer arithmetic/array notation. If you did this and used pointer arithmetic/array notation you were accessing the wrong memory location. -0.5 for shifting second argument by the wrong amount. -0.5 for an incorrect variable declaration. This is a syntax error. -0.5 for not knowing that the xor operator is "^". This is a syntax error. -0.5 for not using the array correctly. This is typically a syntax error. -1 for conditionally accessing the array. The array must be accessed each time through the loop, there is no conditional. -1 not declaring variable types. This is a syntax error and a major language violation. -1 not returning a value. The function must return the result of a calculation. -1 using malloc. There is no dynamically allocated memory, this is a major variable misconception. -1 wrong operation for AND (&) or shift right (>>). This is a syntax error and major language misconception. -1 for using rand() to initialize variables. This is a serious misconception about what kinds of values are valid. -1 for having/calling another function. This is a serious mis-reading of the MIPS code. Function (Major Deductions) For cases where there was an incomplete function, or a very incorrect implementation, we can't grade using the standard deductions. So we grade according to how many valid things are present. +1 shifting the second argument. +0.5 there is a loop. +0.5 there is a return value. +0.5 having the value "8" present for the loop. +1 having the correct mask Part b) 2 points total. -0.5 for using the wrong number of bits. -0.5 for confusing "on" bits and "off" bits -0.5 for confusing >> 4 and /4. -0.5 for multiplying the values from the array. Part c) 3 points total. +1 for every 4 correct values. ##############################################################