views:

195

answers:

5

I'm initializing an unsigned short int with a = 0xff (all bits are set). Then I assign b to a>>7 which should yield (0000 0001) and it does. However, the odd thing is that when I assign c to a<<7, it isn't equivalent to (1000 0000). I tested this by outputting 0x80 (which is 1000 0000) and c, but they aren't the same.

Here is some code:

unsigned short int a = 0xff;
unsigned short int b = a>>7;
unsigned short int c = a<<7; // c should == 0x80

I'm unsure what the problem is. Any help is appreciated. Thanks.

P.S. By "output" I mean output 0x80 and c in decimal and hex form.

+9  A: 

a short int has 16, not just 8 bits.

So you will likely to get "0111 1111 1000 0000" as the result from 0xff<<7.

codymanix
A short could have 8 or 32 bits (even other sizes). int16_t and uint16_t are the only C types that are defined to have 16 bits.
Dan Moulding
No, `short` *cannot* be 8 bits. `short` must have a range of at least `-32767` to `32767`, and `unsigned short` at least `0` to `65535`. 32 bits is OK, though.
caf
"minimum-magnitude value": http://en.wikipedia.org/wiki/Limits.h
Liran Orevi
@Liran: Thanks for the link. I was unaware of the minimum size of short. The general idea I was trying to point out was the common misconception that certain types have certain fixed sizes. short == 16 bits is one such misconception.
Dan Moulding
+5  A: 

Don't guess at bit types, use <stdint.h>

A short int "usually" has 16 bits. Actually, I'm pretty sure it always has 16 except for those Martian computers, but that isn't something the standard promises.

If you want to declare types that have a specific number of bits, the conforming technique is:

#include <stdint.h>

int8_t   a;
uint8_t  b;
int16_t  x;
uint16_t y;

Doing this would have avoided your not-completely-right guess at the bit representation of short. For some reason, Microsoft is a long ways from conforming to the C99 standard, even on easy things like stdint.h>. Fortunately, google has a VC++ version.

DigitalRoss
A: 

Unfortunately, VC++ (the C compiler) does not have inttypes.h because it does not fully support C99. You have to use 3rd-party headers (e.g. Paul Hsieh's stdint.h).

VC++ isn't a C compiler, it's a C++ compiler. C++ compilers don't need to support C99. In an ideal world you should be compiling C with a C compiler, not a C++ compiler, but we unfortunately don't live in an ideal world, so we must sometimes use a jackhammer when all we need is a chisel.
Chris Lutz
@Chris: That may be true about Visual C++, but stdint.h can be correctly implemented in 100% valid C++. It doesn't require any C99 functionality. Given that and the fact that versions of the header are available for VC++, there is no good reason to not use it.
Dan Moulding
VC is a C compiler as well as a C++ compiler - it's not a C99 compiler, however.
Michael Burr
A: 

If you want to get that result, you can chop off the portion a << 7 greater than the 8th-least-significant-bit, using bitwise-and:

unsigned short int c = (a << 7) & 0xff;
caf
+2  A: 

I'd expect that you got 0x7f80. I think what you meant to write is:

unsigned short int c = b<<7; // c should == 0x80

Boojum