-1

Any output of the code is negative when input is positive?

using namespace std;
int aa(int n) //
{
    int i=0;
    for(i=n;i>0;i--)
    {
        i=i*(i-1); //body

    }
    return i; //returning i
}

int main()
{

    cout<<aa(8); //function call

    return 0;
}

Whenever executing the above line of code, why am I getting a negative value? After int range crosses, it should give a garbage value and garbage value could be anything. It shouldn't be necessarily be negative.

bereal
  • 32,519
  • 6
  • 58
  • 104
  • 1
    How do you define `garbage value`? Why do you think your negative result isn't a garbage value? – tkausl May 07 '20 at 09:30
  • 1
    Duplicate of https://stackoverflow.com/questions/29235436/c-integer-overflow – Roy2511 May 07 '20 at 09:31
  • You use one variable for two completely different things, that cannot work. You need separate variable for holding result and for loop control. – Yksisarvinen May 07 '20 at 09:31
  • 1
    You are looping as long as `i>0` and then `return i;`, so the only possible outcomes are `0` and all negative values. – mch May 07 '20 at 09:33
  • @Yksisarvinen maybe that was intended. But to clarify, your loop runs until `i` overflows or gets `0`. Thats the only way your loop breaks. – RoQuOTriX May 07 '20 at 09:34
  • What do you mean by "int range crosses" ? – LeGEC May 07 '20 at 09:39
  • It is an integer overflow. And it is not completely random garbage value. When the value is greater the most signifiant bits are set. The most signifiant bit is also the sign bit. When it was reached, the sign bit is set. If it is set the number is treated as negative. In this case you could probably see set the Overflow Flag in disasm debug. – armagedescu May 07 '20 at 09:44
  • 1
    Does this answer your question? [How do I detect unsigned integer multiply overflow?](https://stackoverflow.com/questions/199333/how-do-i-detect-unsigned-integer-multiply-overflow) – Chandra Shekhar May 07 '20 at 10:24
  • Does this answer your question? [C++ integer overflow](https://stackoverflow.com/questions/29235436/c-integer-overflow) – Ophir Carmi May 07 '20 at 11:37

1 Answers1

1

When n is lower or equal than 2 the value 0 is returned. (Negative does not enter loop, 1 and 2 results in i=0) When larger than 2 the value of i experiences rapid growth because of the line i = i*(i-1), until it overflows. If the overflow result - 1 (because of i--) is positive, the loop continues with the new i. Because the test condition is valid, the rapid growth continues inevitably and results in more and more overflows which will eventually result in number that when decreased 1 value (i--) is a zero or a negative and then the test condition cannot be passed, the for loop ends and i is returned.

Thus positive values cannot be returned, but i could have been the result of a positive overflow result (when the overflow results in 1 and is decreased to 0 by i--).

Observing the special case of aa(8)
First of all aa(8) is called.
int i is created and assigned the value of 0.
The for loop begins. i becomes 8,
8 > 0 so we execute the commands inside the body and set i to 8*7=56 We reached the end of the for so we execute i--, i becomes 55,

Again we check the test condition and 55 > 0 so we execute the commands i = 55*54 again the for block is ended and we execute i-- so i = 2969,

We check the test condition and 2969 > 0 so we execute the commands, i = 2969*2968, we execute i-- so i=8881991.

8881991 > 0 so we execute body i = 8881991*8881990, now there is an overflow and i becomes a negative number, the number is then decreased by i--

but now the test condition i > 0 is false and the loop ends.

i is returned.

Result of an overflow The result of an int overflow can be any of numbers in its range.

Let's say we start counting from zero to represent the said number.

The first number resulting from an overflow is:

cout << INT_MAX+1;

output: -2147483648 (INT_MIN)

We can count further from here so the result can be any of the numbers between INT_MIN & INT_MAX, test:

cout << INT_MAX+n

When n is in range [1 (INT_MIN), 1+INT_MAX+1(0 until here)+INT_MAX(maximum)]

Again we reach INT_MAX and we can continue counting like before...

Nima
  • 381
  • 2
  • 8
  • so according to you, when the range of int is crossed it gets overflow and acquires -ve value? – biswajeet SARKAR May 07 '20 at 10:02
  • Not necessarily, it might be any number in the int range, to understand overflow you should probably read about binary and the Two's complement. When overflow happens the INT_MAX is removed (kind of like mod) and it starts counting from the INT_MIN, the resulting number could be positive or negative. – Nima May 07 '20 at 10:07
  • What i'm saying is that your code is looking for a negative or zero overflow result. Say you get a positive overflow, that number is decreased by 1 and the loop continues on (i > 0) until the overflow result is zero or negative. – Nima May 07 '20 at 10:38
  • Edited furthermore for better understanding. – Nima May 07 '20 at 19:36