2011-01-31 3 views
5

Я знаю, что при делении целых чисел по умолчанию он работает, чтобы отбросить дробную часть. НАПРИМЕР,Деление целых чисел

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); 

Код выше принтами:

N = 0 
Calls = 1 

Не могли бы вы объяснить такое поведение?

+3

Я не понимаю, не ответили ли вы на свой вопрос в первом предложении? –

+0

Не могли бы вы * объяснить, что вы считаете замечательным в этом поведении? –

+0

Думаю, вы найдете мой ответ достаточно. –

ответ

14

1 разделено на 3 = .3333 (повторяется, конечно), математически. Вы можете думать о том, что компьютер обрезает .3333, поскольку он выполняет целочисленную арифметику (0 остаток 1).

Цикл for выполняется потому, что i = 1 и 1 > 0. После выполнения тела цикла, вы разделите i на три и i становится 0, что не больше, чем 0.

+3

@mizo: Нет, условие проверяется перед вводом тела в первый раз. Если вы установите 'i = -1;' в первой части инструкции 'for', тогда тело цикла будет полностью пропущено. –

+1

+1 для geeky Ссылка WoW. Полагаю, я мог бы сделать так, чтобы я был прав, но, черт возьми. Еще 6 сделали это. :) –

+0

@ Джеймс, ты прав. Удален неверный комментарий :) – mizo

1

Потому что он выполняет цикл один раз.

Приращение цикла в for выполняется после того, как тело цикла, и при входе контура i > 0 верно, как 1 > 0, на следующий цикл деления происходит и тогда испытание становится ложным и цикл выхода.

3

переписывают как while и это становится очевидным.

i = 1; 
while (i > 0) 
{ 
    calls++;   
    i /= 3; //This becomes .3333, which truncates to zero 
} 
-2

Все очень просто.

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); 

Надеюсь, это поможет.

+0

@James, вы правы, я отредактировал свой ответ. –

+0

Я не уверен, что я понимаю ваш комментарий относительно pre vs post increment. Поскольку он не фиксирует возврат операции приращения, какая проблема изменяет его на предварительное инкрементное исправление? –

+0

Вся часть приращения до/после не имеет никакого отношения к поведению. Тело цикла выполняется один раз. Это все, что имеет значение. –

1

Где проблема? Первая строка вывода немедленно: 1/3 = 0,33333 ..., удаление дробной части это 0.

Для второй линии иметь в виду, что for цикл переводится на что-то вроде этого:

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

И, в начале i 1; первая итерация while выполняется потому, что i, являющийся 1, больше 0. calls равно 0 и увеличивается на 1, таким образом, доходит до 1. i делится на 3, поэтому он достигает 0 (поскольку дробная часть равна не вычисляется в целочисленном делении). Проверка состояния while выполняется снова, но теперь i равно 0, поэтому цикл не повторяется. calls остается до 1, и это значение выводится на экран.

0

п является INT, подразделение будет возвращать целое число и не двойной или плавать

0

Поскольку в целочисленной арифметике, ответ на 1 делится на 3 равно 0 с остатком 1. Если разделить два целых числа, вы получаете целочисленную арифметику. Если вам нужна арифметика с плавающей запятой, вам нужно, по крайней мере, один из операндов быть значением с плавающей запятой.

Смежные вопросы