0

The Following Programme Is giving The Output as -56.I have manually Traced it -14 binary equivalent is 00001110 and its 2's compliment is 11110001 on left shifting by 2 bits I get as 11000100 .How can I interpret this as -56. Thank You.

#include<stdio.h>

main()

{
int i=-14;
i<<=2;
printf("%d",i);
}
DarenW
  • 16,549
  • 7
  • 63
  • 102
  • -14 cannot be 00001110 because it has not most significiant bit set, thus 00001110 is just 14 not -14. – Zaffy Oct 06 '13 at 06:15

4 Answers4

2

Because it's undefined behavior to left-shift a negative number.

Apart from that: you know that your assumption is only correct if int is one byte/eight bits long? Quite unlikely (especially since the Standard requires it to be at least 16 bits wide).

  • Works for me with 32-bit ints. And two's complement is very well understood. Where is this "undefined"? – Michael Hampton Oct 06 '13 at 06:21
  • AFAIK, the C standard doesn't define the behavior (bitshifting a signed number). – tangrs Oct 06 '13 at 06:22
  • @MichaelHampton For example, [here](http://stackoverflow.com/questions/4009885/arithmetic-bit-shift-on-a-signed-integer/4009922#4009922). Everyone knows that left-shifting a negative number is UB. –  Oct 06 '13 at 06:22
  • Bit shifting doesn't care about sign - it's just a pattern of bits in a CPU register. They get moved a place over, and the "vacuum" created at one end filled with zero (unsigned right shift or a left shift), or retaining its value (signed right shift). I don't know if the official C or C++ standards say anything, but in the real world we bit twiddlers don't worry about it. – DarenW Oct 06 '13 at 06:28
  • @DarenW And that's the problem, that you don't worry about it. Certain processors generate arithmetic exceptions on signed negative shifts, so there's a very good reason (as always) it's undefined. You most certainly don't want to leave this UB in your code. –  Oct 06 '13 at 06:29
  • 1
    Couldn't you cast the number to an unsigned integer type, shift it, then cast back? At the very least, that'd make it implementation defined right? – tangrs Oct 06 '13 at 06:31
  • 1
    @tangrs Exactly. (The thing it makes it implementation-defined is the unsigned to signed conversion, FYI.) –  Oct 06 '13 at 06:33
  • Ahh, gotcha. That makes sense. – tangrs Oct 06 '13 at 06:35
2

Minus 14 should be 11110010. Left shifted 2 places, that gives 11001000.

Assuming two's complement, to convert that to positive, we invert all the bits getting 00110111, then we add 1, getting 00111000. That's 8+16+32 = 56.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

Your original premise is wrong.

-14 in two's complement is not 11110001, it is 11110010.

Thus, when we bit-shift it, we end up with 11001000, which is -56. At least on an Intel CPU with gcc on Linux. YMMV.

Michael Hampton
  • 9,737
  • 4
  • 55
  • 96
0

Fourteen is 00001110 (sticking with eight bits). The 1's complement is 11110001. You need to increment this for the 2's complement: 11110010. (Clue: negative 14 is an even number. Least significant bit should be zero.)

Now shift left two places. 11110010 becomes 11001000. Still a negative value (most sig. bit is set) so let's 2's complement this. First, flip all bits for the 1's complement: 00110111. Now increment: 00111000. This is 56. Note that it's just the starting number, the third "word" in this answer, shifted two places. It all works out nicely, doesn't it?

DarenW
  • 16,549
  • 7
  • 63
  • 102
  • Note that if you are dealing with 32 bit or 64 bit values (or 27 bit if you're using an old Minuteman guidance computer, whatever...) the higher bits are just the same value repeated as you see in the MSB in the examples shown. – DarenW Oct 06 '13 at 06:31