10
\$\begingroup\$

I am going through the Coursera course The Hardware/Software Interface and because it has already ended, I would not be able to get any feedback on the code.

The assignment is:

LogicalShift: shift x to the right by n, using a logical shift. We can assume that 0 ≤ n ≤ 31.

I am wondering if shifting by n and then back by 1 is a good solution.

int logicalShift(int x, int n) {
  int ba = 1<<31; // set MSB to 1 
    int a = x & ba; // MSB will be 1 if negative or 0 if positive number

    int numShifted = x>>n; //shift the number
    int msbShifted = (a >> n) << 1; //shift the MSB by n -1 

    //if negative ^ the leading 1's to create a logical shift
    return msbShifted ^ numShifted;
}
\$\endgroup\$
12
\$\begingroup\$

The C standard does not guarantee that an int is 32 bits. Even though the problem guarantees that 0 ≤ n ≤ 31, your code fails if run on a machine with a 64-bit int. One way to resolve that problem is to be explicit about the size of your inputs:

#include <stdint.h>

int32_t logicalShift(int32_t x, int n) {
    …
}

The C standard says (C99 §6.5.7):

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of \$\dfrac{\mathrm{E1}}{2 ^ \mathrm{E2}}\$. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

Therefore, your best bet is to treat x as an unsigned type:

int logicalShift(int x, int n) {
    return (unsigned int)x >> n;
}
\$\endgroup\$
  • \$\begingroup\$ Thank you for the reply. It makes sense to me that my solution wouldn't work if machine is 64bit. This is just beginning of the class where they teach binary numbers unsigned and signed, shifts and other operations. For the purpose of the assignment it assumed that the machine is 32bit. I wanted to know if logically this make sense of shifting by n and back by 1 is kinda hacky. \$\endgroup\$ – Yan Oct 8 '14 at 2:11
  • \$\begingroup\$ Yan, no it makes no sense. 200_success has given you the correct answer. The purpose of the question is probably to see whether you understand the difference between a logical shift (>>, <<) and an arithmetic shift (integer multiply/divide in C). You are also assuming the coding system (2's complement etc), which is not a valid thing to do. \$\endgroup\$ – William Morris Oct 8 '14 at 23:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.