0

I'm using MSVC 2019.

So, I just searched here. They says that long long is 8 byte, and range of values is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

So, what I thought is, that this would work:

long long a = 2147483648 + 2147483648;
printf("%lld", a);

I thought it would print 4294967296, which equals to 2147483648 + 2147483648.

But it prints 0 to me.....

So, this time I tried little differently:

long long a = 2147483648;
printf("%lld", a + a);

and it prints 4294967296!!!

So here are two questions.

FIRST: What is difference between those codes?

SECOND: Why the first code gives me wrong number(0)?

Thanks in advance :)

Daniel A. White
  • 174,715
  • 42
  • 343
  • 413
Hoseong Jeon
  • 1,150
  • 8
  • 20

3 Answers3

3

The result of 2147483648 + 2147483648 depends on the type of 2147483648 , it does not take into account that you later store the result into a long long variable.

MSVC's C compiler does not conform to the C99 or later standards, and it makes 2147483648 have the type unsigned long which is a 32-bit type. (This was correct behaviour in C90). Then the result of the addition is (unsigned long)0 as per the definition of unsigned arithmetic.

M.M
  • 130,300
  • 18
  • 171
  • 314
  • Okay, got it. Then if I plus three times, like this: `long long a = 2147483648 + 2147483648 + 2147483648;`, it gives me `2147483648`!! `2147483648 + 2147483648 = 0`, and isn't `0 + 2147483648 = -2147483648` because `0` and `2147483648` are `int`? – Hoseong Jeon May 06 '20 at 01:26
  • Ahh... I'm getting dizzy.... LOL – Hoseong Jeon May 06 '20 at 01:31
2

FIRST: What is difference between those codes?

long long a = 2147483648 + 2147483648;

This actually works as-intended with GCC (it prints 4294967296), but VC++ prints 0.

long long a = 2147483648;

The results are different because in the first case the integer literals are added as though they're int, not long long so the intermediate result overflows.

In the second case the addition is correct because there's no overflow because the + operator is being used with long long operands.

SECOND: Why the first code gives me wrong number(0)?

Integer literals are typed as int by default unless you specify a type suffix. The C++ compiler will not automatically widen integers (even though in this case the context and developer's intent is clear).

So this code...

long long a = 2147483648 + 2147483648;

...is equivalent to this:

int x = 2147483648;
int y = 2147483648;
int z = x + y;
long long a = z;

You can fix this by using the long integer literal suffix: LL:

long long a = 2147483648LL + 2147483648LL;
Dai
  • 110,988
  • 21
  • 188
  • 277
  • 1
    Your equivalence would not hold on any system with 32-bit `int` (since the constant is too large for `int` and therefore has some other type) – M.M May 06 '20 at 01:08
2

The constant 2147483648 is an unsigned int (or unsigned long) literal and, as such, is a 4-byte value on the platform you are using. Thus, when you add two such constants together (as in your first code snippet), the operation is performed in 4 bytes, and overflows (giving zero). Only after the addition is performed is the result promoted to a long long (but, by then. the damage is done).

In your second code snippet, you are adding two variables that are explicitly declared as long long and, thus, the addition is performed as an 8-byte operation.

To 'fix' the first snippet, and force the constants to be 8-byte values, you need to add the LL (or ll) suffix:

long long a = 2147483648LL + 2147483648LL;
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
Adrian Mole
  • 30,672
  • 69
  • 32
  • 52