1

I am a beginner in The C programming language and was writing a program which shows integer overflow in action, here is the code below:

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

int main(){

int n1;
int n2;

printf("enter a number: ");
scanf("%d", &n1);

printf("enter a number: ");
scanf("%d", &n2);

printf("\n%d\n", n1*n2);

    return 0;
}

As you may be able to tell it takes two numbers from the user and times them together and outputs the value to the user, I was working with this program and input a value of 200000000000 x 200000000000, this gave me the output of -922746880. My question is that why do i get a random negative value such as this and what is the math and calculations behind it? so i can get a better understanding.

So far i am aware that the maximum value of the integer data type is 2,147,483,647 for a 32-bit cpu. But when 200000000000 x 200000000000 is being calculated, what happens to each digit calculated and why is it negative?

P.S can somebody please explain the math and behind the scene number action going on so i can see what actually happens for this value to be displayed.

  • [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) – Barmar Jul 01 '20 at 18:06
  • 1
    -922746880 is not a random value, you can do 200000000000 times the same computation in your program and you will always get the same result. It is considered negative because the result value has the upper bit to 1 and in your case the representation is the two's complement and you print it as an `int`. You can compute using `long long` then cast to `int` and you will have the same result – bruno Jul 01 '20 at 18:08
  • 1
    In the example you tried, the arithmetic has wrapped modulo 2^32, effectively taking just the last 32 bits of each operation. In hexadecimal, 200000000000 is 0x2e90edd000. The last 32 bits are 0x90edd000. When that is multiplied by itself, the result is 0x520c66eac9000000. The last 32 bits of that are 0xc9000000. As an unsigned value, that is 3372220416 in decimal. However, the high bit of those is set, so it is interpreted as a negative number, effectively subtracting 2^32 (4294967296). The result is −922746880. – Eric Postpischil Jul 01 '20 at 18:10
  • The behavior is *undefined* - there is no specific calculation behind what you get. The most likely reason that the value is negative is that the uppermost bit has been set, and in most signed integer representations that's how you indicate a negative value. – John Bode Jul 01 '20 at 18:11
  • Also, please do not call this is a “random” value. “Random” has a specific meaning regarding probability and lack of control or method. Values such as these result largely from deterministic processes. They may be processes unknown to you and unspecified by the C standard, but they are mechanical in nature, not random. (In various situations, results may be a mix, coming from some mix of truly random or attempted random processes such as address space layout randomization and mechanical deterministic processes, but you should still not describe them as “random” unless they are.) – Eric Postpischil Jul 01 '20 at 18:13
  • @EricPostpischil I'm a bit of a beginner in C could you please explain that in a more beginner friendly way my friend? Also JohnBode says the value is undefined and has no specific calculation? –  Jul 01 '20 at 18:17
  • 1
    @Qasim: Essentially every operation is performed modulo 2^32: The result is as if the full mathematical result were calculated and then replaced with its remainder when divided by 2^32 (yielding a number from −2147483648 to +2147483647). The statement there is no specific calculation behind what you get is false. The C standard does not specify what happens with overflow, but that does not mean that reasons and mechanisms do not exist at all. They do exist, and they vary from C implementation to C implementation and from situation to situation, but what happened in your case is as I described. – Eric Postpischil Jul 01 '20 at 18:45
  • @JohnBode Thank you for your answer but what do you mean when you say "that the uppermost bit has been set"? what does this mean exactly –  Jul 04 '20 at 12:26
  • @EricPostpischil Hmm okay so is this what always happens when the answer "wraps" during integer overflows? –  Jul 04 '20 at 12:27
  • 1
    @Qasim: The C standard does not require it to, so you cannot rely on this without assurances from other sources, such as the documentation for a particular compiler. GCC does provide wrapping behavior for signed integers (subject to selection by command-line switches). The results in your case are as if wrapping occurred. However, other possibilities include clamping (using the maximum representable value, such as 0xFFFFFFFF, instead of wrapping), using uncontrolled data (whatever happened to be in some register), and generating a trap. – Eric Postpischil Jul 04 '20 at 12:39
  • @EricPostpischil: In gcc, it's also possible for integer overflow within a function to arbitrarily disrupt the behavior of calling code, even if the overflow occurs within computations like `(ushort1 * ushort2) & 0xFFFFu)` which the Committee expected most commonplace implementations to process in a fashion equivalent to `(1u * ushort1 * ushort2) & 0xFFFFu)`. – supercat Jul 15 '20 at 20:46

0 Answers0