In C, why can't I shift a 64-bit integer more than 32 bits?

I'm using Mingw's compiler, and UEStudio.

When I try to shift a 64-bit integer more than about 32 bits, I get zero for the result. I've googled and googled, and can't find an answer.

Here is the pertinent code:
unsigned long long int MyLongLong;
unsigned long long int ShiftAmount;


MyLongLong = 1;
ShiftAmount = 13;

printf("%016LLX\n", MyLongLong);

MyLongLong = MyLongLong << ShiftAmount;
printf("%016LLX\n", MyLongLong);

MyLongLong = MyLongLong << ShiftAmount;
printf("%016LLX\n", MyLongLong);

MyLongLong = MyLongLong << ShiftAmount;
printf("%016LLX\n", MyLongLong);

Open in new window

This prints into the console:

I'd looooove any ideas!
--Steve D.
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenDBACommented:
Hi Steve,

The shift count is probably just an integer (not a long or long/long).  :)

I'd add another test.  After line 18, add this:

MyLongLong = MyLongLong >> ShiftAmount;
printf("%016LLX\n", MyLongLong);

That will show us whether the shift is truly failing or if the output format is dropping the upper 32 bits.

You have upper case Ls in your printf which is for doubles. Try changing them to lower case for 64 bit integer.
StevenMilesAuthor Commented:
HA!! Doing the right shift showed that the shift is happening, but I just can't print it out!

I thought I was going crazy.

But now, how do I print it out? I've tried these, without success:
%16llX, then I realized my "X" was capital, so I used
%16llx, and
%llx , which also shows a zero result, but the right shift proves that the value is not zero.
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

StevenMilesAuthor Commented:
FWIW, "llu" also prints out zero for the higher numbers.
Kent OlsenDBACommented:
Start with the basics.

Use "%llu" as the formatter.  You can modify it once you're comfortable that it works.
Kent OlsenDBACommented:
Ah.  Sorry.

Try "%I64d" for integer and "%I64x" for hex.
What version of C/C++ are you using? What compiler?
StevenMilesAuthor Commented:
I'm using the very latest installation from MinGW, I think. I just installed it yesterday:
C:\MinGW\bin>gcc --version
gcc (GCC) 4.8.1

C:\MinGW\bin>g++ --version
g++ (GCC) 4.8.1

In place of where I had the printf statements, I made a call to this function I just wrote:

void Print_64_bit(unsigned long long int printThis) {
	unsigned long long int highorder;
	unsigned long long int loworder;
	highorder = printThis;
	loworder = printThis;
	highorder = highorder >> 32;
	printf ("0x");
	printf ("%08llx",highorder);
	printf ("%08llx\n",loworder);

Open in new window

And the output now looks like this (for ShiftAmount=15):

So it would seem that I can proceed with my programming, because I now know how to print out a 64-bit integer. And it's easy. But this is a kludge. I still don't really understand what's going on.
MinGW uses the Win32 Runtime so Kdo's suggestion to use %l64x should work. Windows doesn't respect the ll specifier.
Kent OlsenDBACommented:
Hi Steven,

I downloaded the GCC compiler and to my Windows environment and tried this.  It looks like just lower casing the items in the format string will work.

  printf("%16.16llx\n", MyLongLong);
  printf("%016llx\n", MyLongLong);

Both of those lines printed the desired results for me, using the 32-bit compiler 4.9.3.  

Good Luck!
StevenMilesAuthor Commented:
Okay, folks,

I appreciate all the help, and you don't have to keep racking your brains, but it's not working. However, it doesn't really matter right now, since my kludge is fine.

I tried "%l64x" but that prints out "64x" for MyLongLong, not even the bits.

I also tried   "%16.16llx\n"  and    "%016llx\n" but they had the same problem: after 32 bits, the printout was all zeroes.

I'm at a loss, but as I said, I'm in business again with the kludge. I'll distribute points around; I always appreciate the help, even if a solution isn't found.
Kent OlsenDBACommented:
Just to make sure, but "I64" is eye-sixty-four, not ell-sixty-four.  :)

Also, whenever I display hex or octal values I invariable split full words for readability.

printf ("%04x %o4x  %o4x %o4x\n",
  MyLongLong >> 48,
  (MyLongLong >> 32) & 0xFFFF,
  (MyLongLong >> 16) & 0xFFFF,
  MyLongLong & 0xFFFF);

It's much easier to identify stray bits this way, and it will work even your your environment.

And if it's a memory dump or similar, I take it a step further and replace all zero ("0000") with all dashes ("----"), making it trivial to identify the non-zero values.

Sorry that we couldn't fix this for you!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
StevenMilesAuthor Commented:
Oh how embarrassing. I must be sleeping through this week.

%I64x , with an "eye", works!! So if I use %016I64x, I can get 16 digits no matter where the bits are set. Wow.

And, I love your idea of re-formatting it. Actually, I had already updated my Print_64_bit function from above, to make the hex printout not like this:

but rather like this:
0x 2345-6734-2879-8304

Much more readable. Maybe spaces here are better than hyphens, and I can use hyphens for the zeros.

Thanks again.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.