Question: Source Code:
------------

```
#include <iostream>
using namespace std;
int main() {
        unsigned long P;

        P = 0x7F << 24;
        cout << P << endl;

        P = 0x80 << 24;
        cout << P << endl;

        return 0;
}

```

Output:
-------

```
2130706432
18446744071562067968

```

As you can see, the first result is correct.
But the second result is extremely wrong.
The expected result is 2147483648 and it does not match with 18446744071562067968.

I want to know why

Answer: 
The type of the expression `0x80 << 24` is not `unsigned long`, it’s `int`. You then assign the *result* of that expression to `P`, and in the process convert it to an `unsigned long`. But at that point it has already overflown (incidentally causing undefined behaviour). Use `unsigned long` literals in your expression:

```
P = 0x80ul << 24;

```
This problem is not entirely portable, since it depends on the number of bits in your representation of `unsigned long`. In this case, there is an overflow followed by an underflow, and the two effects combine to produce your surprising result.

The basic solution is indicated here: [ULL suffix on a numeric literal](https://stackoverflow.com/q/8809292/86967)

I've broken it down in the code below.

---

```
#include <iostream>
using namespace std;
int main() {

        cout << "sizeof(unsigned long) = " << sizeof(unsigned long) << "\n";
        cout << "sizeof(0x80) = " << sizeof(0x80) << "\n";

        int32_t a = (0x80 << 24); // overflow: positive to negative
        uint64_t b = a; // underflow: negative to positive

        uint64_t c = (0x80 << 24); // simple broken
        uint64_t d = (0x80UL << 24); // simple fixed
        uint32_t e = (0x80U << 24); // what you probably intended

        cout << "a = " << a << "\n";
        cout << "b = " << b << "\n";
        cout << "c = " << c << "\n";
        cout << "d = " << d << "\n";
        cout << "e = " << e << "\n";

}

```

Output:

```
$ ./c-unsigned-long-cannot-hold-the-correct-number-over-2-147-483-647.cpp 
sizeof(unsigned long) = 8
sizeof(0x80) = 4
a = -2147483648
b = 18446744071562067968
c = 18446744071562067968
d = 2147483648
e = 2147483648

```

---

If you're doing bit-shift operations like this, it probably makes sense to be explicit about the integer sizes (as I have shown in the code above).

* [What's the difference between long long and long](https://stackoverflow.com/q/6462439/86967)
* [Fixed width integer types (since C++11)](https://en.cppreference.com/w/cpp/types/integer)