-1

So I am trying to solve this home assignment and I have been stuck with this one particular problem for a couple of hours and can't figure it out. I feel like I am so close! But then i change something in the code and something else isn't right..

/*
 * logicalShift - shift x to the right by n, using a logical shift
 *   Can assume that 0 <= n <= 31
 *   Examples: logicalShift(0x87654321,4) = 0x08765432
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3
 */
int logicalShift(int x, int n) {

    int move;
    int y;
    y = x >> n;
    y = ~y << 1;
    move = (y & (x >> n));

    return move;
}

What is missing here? I get 0x80000000 >> 31 as 0 but should be 1 - But other than that I don't know..

phuclv
  • 37,963
  • 15
  • 156
  • 475
drleifz
  • 189
  • 3
  • 12
  • [Perform logical shift using arithmetic shift operator in C](https://stackoverflow.com/q/17893901/995714) – phuclv Jan 26 '19 at 01:32

2 Answers2

0

C's >> operator already performs a logical right shift on an unsigned integer. Does this do what you want?

#include <stdio.h>

unsigned long int logicalShift(unsigned long int x, unsigned int n) {
  return x >> n;
}

int main() {
  unsigned long int value = 0x80000000UL;
  unsigned int shift_amt = 31;
  unsigned long int result = logicalShift(value, shift_amt);
  printf("0x%lx >> %d = 0x%lx\n", value, shift_amt, result);
  return 0;
}

Result:

0x80000000 >> 31 = 0x1

If you are not allowed to cast to an unsigned data type, then the result of right shifting a signed value in C is implementation defined, according to this answer by Ronnie which cites K&R Second Edition. Even if this possible homework assignment were amended to allow the division operator, the alternate solution involving an elaboration on `x / (1 << n)' is also problematic because the rounding for division involving a negative number is also implementation-defined prior to C99. So unless you can tell us which C implementation your instructor is using and which ABI it implements, this question would appear to have no answer that is both easy and portable.

Community
  • 1
  • 1
Damian Yerrick
  • 4,602
  • 2
  • 26
  • 64
  • I am not allowed to change the data type :/ – drleifz Sep 21 '14 at 23:21
  • @drleifz: Well that's inconvenient. What else are you not allowed to do? Can you use a cast? – Greg Hewgill Sep 21 '14 at 23:27
  • I am only allowed to use the bit-wise operators (! ~ & ^ | + << >>) . Not allowed to use casting, if-statements, functions or anything like that :) – drleifz Sep 21 '14 at 23:31
  • You've already used assignment (`=`) which is not in your list of permitted operators. Might want to review those requirements and make sure you're on the right track. – Greg Hewgill Sep 21 '14 at 23:34
  • = is not considered a bit-wise operator according to the teacher. But I am allowed to use those bit-wise operators above including (=) but excluding (-, &&, ||, if-statements, functions) – drleifz Sep 22 '14 at 12:58
  • actually right shift is [implementation defined behavior](http://stackoverflow.com/questions/13544519/bitwise-shift-operators-on-signed-types) so you can't simply cast the value to unsigned and hope it'll work on all platforms – phuclv Nov 10 '14 at 16:42
0

0x80000000 >> 31 = 1 if it's a logical shift.

0x80000000 >> 31 = -1 if it's an arithmetic shift.

In C++, if the value being shifted is unsigned, it is logical shift.

In Java, >> is arithmetic shift. >>> is logical shift.

anonymous
  • 1,317
  • 8
  • 7
  • 0x80000000 should be 1 if shifted with the logical shift 31. – drleifz Sep 21 '14 at 23:26
  • Yeah. sorry.. miscalculate. – anonymous Sep 21 '14 at 23:38
  • right shift in C it's [implementation defined](http://stackoverflow.com/questions/8422424/can-you-control-what-a-bitwise-right-shift-will-fill-in-c), so you can't rely on unsigned types being logical shift on all platforms – phuclv Nov 10 '14 at 16:51