Pregunta

Why do these programs produce different outputs?

Program 1:

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller * 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

Output:

Smaller = 2147483647

Bigger = smaller * 2 = -2


Program 2:

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller;
    bigger *= 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

Output:

Smaller = 2147483647

Bigger = smaller * 2 = 4294967294


My guess is that program 1 attempts to store the multiplication result in a temporary storage which is of the same size as int. So it overflows. Whereas, program 2, stores the multiplication result in the larger storage.

Am I correct?

Additionally, if I have made any grievous mistake in either of the programs, please let me know (because according to me, those programs compile perfectly)!

¿Fue útil?

Solución

smaller is an int, so is the literal 2. So their product is an int too. Since INT_MAX * 2 can't be represented by an int (by definition, pretty much), it overflows leading to undefined behavior.

If, however, you store the value in a long long, then, when performing the multiplication, default integer promotion (the "usual arithmetic conversion") happens. Now, if your long long can represent INT_MAX * 2, you will end up with something semantically equivalent with bigger = bigger * (long long)2, which works as expected.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top