[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]
Represent each of the following using the 8-bit two's-complement integer representation we saw in class.
| a. | 10 |
| b. | −60 |
| c. | −104 |
| a. | 10 | becomes | 0000 1010 |
| b. | −60 | becomes | 1100 0100 |
| c. | −104 | becomes | 1001 1000 |
| a. | −1(10) | in a seven-bit two's-complement format |
| b. | −20(10) | in a seven-bit two's-complement format |
| c. | 20(10) | in a seven-bit two's-complement format |
| d. | −300(10) | in twelve-bit two's-complement format |
| a. | −1(10) | 111 1111 |
| b. | −20(10) | 110 1100 |
| c. | 20(10) | 001 0100 |
| d. | −300(10) | 1110 1101 0100 |
| a. | Sign-magnitude: | 111 1111 represents −63(10) |
| b. | Two's-complement: | 100 0000 represents −64(10) |
What is the value of each of the following C expressions?
a. 10 & 24
b. 10 | 24
c. 10 ^ 24
d. 1
a. 10 & 24 = 8
b. 10 | 24 = 26
c. 10 ^ 24 = 18
d. 1 = 1
What is the hexadecimal value of each of the following C expressions?
a. 0x3C & 0x55
b. 0x3C | 0x55
c. 0x3C ^ 0x55
d. ~0x3C
e. 0x3C << 2
a. 14(16)
b. 7D(16)
c. 69(16)
d. FFFFFFC3(16)
e. F0(16)
>> does an
arithmetic shift.
| a. | (-16) ^ 3 = |
| b. | (-10) >> 2 = |
| a. | (-16) ^ 3 = | −13 |
| b. | (-10) >> 2 = | −3 |
Explain the distinction betwen arithmetic and logical right-shift. Why is arithmetic right-shift so popular?
Both behave the same when shifting a number whose topmost bit is 0; but when the topmost bit is 1, the arithmetic right-shift will fill in the vacated top bits with 1's, whereas the logical right-shift will fill with 0's. The arithmetic right-shift is commonly used because with two's-complement representation, it effectively divides the number by a power of two: An arithmetic right-shift by two places, for example, is equivalent to dividing by four.
What would the following C program print when run?
#include <stdio.h>
int mystery(int n, int i) {
return (n >> i) & ~(-1 << i);
}
int main() {
printf("%d %d %d %d\n", mystery(0xFF, 2), mystery(0xFF, 5),
mystery(0x77, 3), mystery(0x02040608, 8));
return 0;
}
3 7 6 6
int f(int x, int n) {
return x | (1 << (n - 1));
}
| a. | What does f(0, 2) return? |
| b. | What about f(8, 3)? |
| c. | What about f(8, 4)? |
| d. | What about f(f(0, 1), 2)? |
| a. | 2 |
| b. | 12 |
| c. | 8 |
| d. | 3 |
Complete the following function so that it returns 1 if the
parameter number is negative and 0 otherwise. The only type of
statement you should use is the return statement, and the only operators you should use are the bit operators (~ & | ^ >> <<).
You may assume that the computer uses 32-bit integers.
int sign(int query) {
return
}
int sign(int query) {
return (query >> 31) & 1;
}
Suppose we have an int value containing seven
four-bit values packed together.
Complete the following C function so that it adds all seven values
together using only three additions.
For example, given the value 0x31320BF, the function
should return
3 + 1 + 3 + 2 + 0 + 11 + 15 = 35.
The only operators used
should be the bit operators and the three addition operators.
The only statements should be variable declarations, assignment
statements, and a return statement.
int addNibbles(int x) {
int addNibbles(int x) {
x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
return (x & 0xFFFF) + ((x >> 16) & 0xFFFF);
}
Without using any of the arithmetic operators (+, -, *, /, %), complete the following C function so that it returns the largest power of 2 that fits into its parameter. For example, maxPow2(20) is 16, and maxPow2(32) is 32. You may assume that the parameter is a positive integer. Note: You may use loops and conditional statements, but you should not call other functions.
int maxPow2(int n) {
int maxPow2(int n) {
int k;
int ret;
for(k = 1; k > 0; k <<= 1) {
if((n & k) != 0) ret = k;
}
return ret;
}