-1

I know there are many topics on this subject but none of them helped me to fix my problem. I work on Code::Blocks (with the option -std=c99 in "Properties>Project Build Options>Compiler Settings>Other Options") and the following code doesn't give the expected output:

long long val=1<<33;
printf("value: %llu",val);

In fact I obtain "value: 0" in the terminal. How can I fix that problem?

When I write 30 instead of 33 (so val is an integer), I get the rigth answer. I have also tried %lld but that does not help.

fonfonx
  • 1,475
  • 21
  • 30

3 Answers3

3

1<<33 will invoke undefined behavior for 32 bit int.

C11: 6.5.7 Bitwise shift operators:

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
3

Since you haven't qualified the literals 1 and 33 in any way, 1<<33 will have an int as its type. If int is 32 bit (very common on compilers targeting 64 bit) then this expression will yield undefined behaviour.

A simple fix would be to write 1LL << 33. 1LL is a long long, and 33 will be promoted to that type too. The C++ standard guarantees that long long is at least 64 bits.

In many ways though I prefer static_cast<std::int64_t>(1) << 33.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • The operands of `<<` and `>>` don't undergo usual arithmetic conversions. Having 33 promoted to `long long` in `1LL << 33` is a K&R C thing (the fact that K&R C didn't have `long long` aside). – mafso Mar 18 '15 at 18:02
1

The shift 1<<33 is not done on a long long type. The 1 is an int here; cast it to long long or suffix it with LL, e.g., 1LL << 33.

Arkku
  • 41,011
  • 10
  • 62
  • 84