5

I know when dividing integers the default way it works is to discard the fractional part. E.g.,

int i, n, calls = 0;
n = 1;
n /= 3;
printf("N = %i\n", n);
for (i = 1; i > 0; i /= 3) {
    calls++;
}
printf("Calls = %i\n", calls);

The code above prints:

N = 0
Calls = 1

Could you please explain this behavior?

Chris Smith
  • 18,244
  • 13
  • 59
  • 81
Radek Simko
  • 15,886
  • 17
  • 69
  • 107

7 Answers7

13

1 divided by 3 = .3333 (repeating of course), mathematically. You can think of the computer as truncating the .3333 since it is doing integer arithmetic (0 remainder 1).

The for loop executes because i = 1 and 1 > 0. After executing the body of the loop, you divide i by three and i becomes 0, which is not greater than 0.

Chad La Guardia
  • 5,088
  • 4
  • 24
  • 35
  • 3
    @mizo: No, the condition is checked before the body is entered for the first time. If you set `i = -1;` in the first part of the `for` statement, then the body of the loop will be skipped entirely. – James McNellis Jan 31 '11 at 23:10
  • 1
    +1 for geeky WoW reference. I suppose I could have +1'ed for being correct, but, heck. 6 others did that already. :) – John Dibling Jan 31 '11 at 23:13
  • @Chad: I think this is a little misleading - as if the computer was doing floating point maths then truncating. You might consider qualifing that first statement with "Mathematically, ", and reword the truncation bit? It's more correct to describe it like humans doing maths ala "x / y = n remainder r, but remainers are discarded". – Tony Delroy Feb 01 '11 at 01:28
  • @Tony I agree with what you are saying there. It is true that the computer does not have any sense of what that decimal is since it is simply doing integer division. I'll make that clarification. – Chad La Guardia Feb 01 '11 at 04:04
  • Actually, to add to what I said, MOST computers would ignore the decimal part. ICBW, but I do believe that some microcontollers only have floating point division, which means that it is "truly" truncating when they do integer division. – Chad La Guardia Feb 01 '11 at 04:15
3

rewrite as while and it becomes apparent.

i = 1;
while ( i > 0 )
{
    calls++;        
    i /= 3; //This becomes .3333, which truncates to zero
}
James
  • 5,355
  • 2
  • 18
  • 30
1

Because it executes the loop once.

The loop increment in for is executed after the loop body, and at loop entry i > 0 is true as 1 > 0, on the next loop division occurs and then the test become false and loop exit.

kriss
  • 23,497
  • 17
  • 97
  • 116
1

Where's the problem? The first line of output is immediate: 1/3=0.33333..., removing the fractional part it's 0.

For the second line keep in mind that the for cycle is translated to something like this:

i=1;
while(i>0)
{
    calls++;
    i/=3;
}

So, at start i is 1; the first iteration of the while is executed because i, being 1, is greater than 0. calls is 0 and is incremented by 1, thus gets to 1. i is divided by 3, so it gets to 0 (because the fractional part is not computed in integer division). The while condition check is performed again, but now i is 0, thus the cycle is not repeated. calls remains to 1 and this value is printed on the screen.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
0

n is an int, a division will return an integer and no double or float

Van Coding
  • 24,244
  • 24
  • 88
  • 132
0

Because in integer arithmetic, the answer to 1 divided by 3 is 0 with a remainder of 1. If you divide two integers, you get integer arithmetic. If you want floating point arithmetic, you need at least one of the operands to be a floating point value.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
-2

It's all very simple.

int i, n, calls = 0; // Set calls to 0
n = 1;               // n is now 1
n /= 3;              // n /= 3 = 1/3 = 0
printf("N = %i\n", n);
for (i = 1; i > 0; i /= 3) { // 1/3 = 0
    calls++;                 // runs once
}                            
printf("Calls = %i\n", calls);

Hope this helps.

Charles Ray
  • 470
  • 1
  • 5
  • 16
  • I'm not sure I understand your comment regarding pre vs post increment. Since he's not capturing the return of the increment operation, what problem does changing it to pre-increment fix? – Benjamin Lindley Jan 31 '11 at 23:15
  • The whole pre/post increment part has no relevance to the behavior whatsoever. The body of the loop is executed once. That's all that matters. – Jeff Mercado Jan 31 '11 at 23:20
  • That comment is wrong altogether. It doesn't return to the orignal number. Calls++ means evaluate line of code, then increment. ++Calls means increment, then evaluate line of code. Either way, after that line it will still be one. The i /= 3 is evaluated after the for loop, so it performs the loop once. – Lee Louviere Jan 31 '11 at 23:24