Почему это деление дает ноль?

Я писал этот код на C, когда столкнулся со следующей проблемой.

#include <stdio.h>
int main()
{
   int i=2;
   int j=3;
   int k,l;
   float a,b;
   k=i/j*j;
   l=j/i*i;
   a=i/j*j;
   b=j/i*i;
   printf("%d %d %f %f\n",k,l,a,b);
   return 0;
}

Может ли кто-нибудь сказать мне, почему код возвращает ноль для первой и третьей переменных (k и a)?


person sandy101    schedule 14.10.2009    source источник
comment
Какие ошибки вы получаете? Какого результата вы ожидаете? Какой результат вы получаете?   -  person Thomas Owens    schedule 14.10.2009
comment
обратите внимание, что у вас есть / n вместо \ n. Это копипаст вашего кода или вы его повторно набирали? Лучше иметь копипаст, чтобы избежать ошибок транскрипции.   -  person John Carter    schedule 14.10.2009
comment
Я изменил заголовок / вопрос на то, что, по моему мнению, было предназначено   -  person John Carter    schedule 14.10.2009
comment
@therefromhere: вы просто угадываете, и исправление вопроса не помогает тому, кто задает вопрос, научиться задавать вопросы лучше.   -  person Greg Hewgill    schedule 14.10.2009
comment
Верно, но может помочь следующим людям, которые используют Google в этом направлении.   -  person John Carter    schedule 14.10.2009
comment
(Я согласен с тем, что это довольно экстремальное редактирование, но это настолько распространенная ошибка новичков, что я подумал, что стоит нанести удар)   -  person John Carter    schedule 14.10.2009


Ответы (6)


Я думаю, вы испытываете целочисленную арифметику. Вы правильно полагаете, что l и b равны 2, но неверно предполагаете, что k и a будут равны 3, потому что это одна и та же операция. Но это не так, это целочисленная арифметика (а не арифметика с плавающей запятой). Поэтому, когда вы выполняете i / j (пожалуйста, подумайте об использовании некоторого пробела), 2/3 = 0,33333 ... , которое преобразуется в int и, таким образом, становится 0. Затем мы снова умножаем на 3 и 0 * 3 = 0.

Если вы измените i и j на floats (или добавите в математику (float) приведений), это будет делать то, что вы ожидаете.

person Chris Lutz    schedule 14.10.2009

Вы спрашиваете, почему k и a равны нулю? Это связано с тем, что при целочисленном делении 2/3 = 0 (дробная часть усекается).

person bobbymcr    schedule 14.10.2009
comment
В дополнение к этому, когда вы пишете = ‹expr›; с объявленным числом с плавающей запятой только результат - person Steve314; 14.10.2009
comment
Это также относится к a, потому что он выполняет там ту же операцию (i / j == (int) 2 / (int) 3 == 0) - person T.E.D.; 14.10.2009

Вы не сказали, что получаете или чего ожидаете, но в этом случае, вероятно, легко догадаться. Когда вы делаете 'a = i / j * j', вы ожидаете, что результат будет примерно 0,2222 (т.е. 2/9), но вместо этого вы получите 0,0. Это связано с тем, что i и j оба являются числами типа int, поэтому умножение и (что особенно важно) деление выполняются с помощью целочисленной математики, что дает 0. Вы присваиваете результат float, так что 0 затем преобразуется в 0,0f.

Чтобы исправить это, преобразуйте хотя бы один операнд в число с плавающей запятой ПЕРЕД делением: a = (float)i/j*j);

person Jerry Coffin    schedule 14.10.2009

это связано с тем, как компилятор c обрабатывает int в разделах:

 #include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j; // k = (2/3)*3=0*3=0
l=j/i*i; // l = (3/2)*2=1*2=2
a=i/j*j; // same as k
b=j/i*i; // same as b
printf("%d %d %f %f/n",k,l,a,b);
return 0;
}
person Amirshk    schedule 14.10.2009

Если вы спрашиваете, почему k и a равны 0: i/j*j совпадает с (i/j)*j. Поскольку j больше i, i/j равно 0 (целочисленное деление). 0*j по-прежнему 0, поэтому результат (k) равен 0. То же самое относится и к значению a.

person sepp2k    schedule 14.10.2009

не имеет значения, является ли у вас переменная с плавающей запятой или нет, пока вы используете

целое / целое число, вы получите 0,

но поскольку вы используете вывод с плавающей запятой, вы получаете 0,0

person lorde    schedule 04.10.2018