2014-10-24 4 views
0

Я практически новичок в программировании на С, и я пытался получить простую среднюю функцию, но дробная часть ответа продолжает испортить ... ??Неверный ответ средней функции?

#include <stdio.h> 
#include <float.h> 

float cal(int num1,int num2,int num3); 

int main(){ 
    int a,b,c; 
    float avg; 

    a=10; 
    b=5; 
    c=11; 

    avg=cal(a,b,c); 
    printf("Average is : %E\n", avg); 
    return 0; 
} 

float cal(int num1,int num2,int num3){ 
    float avg1; 
    avg1=(num1+num2+num3)/3; 
    return avg1; 
} 

Ответ (avg) должен быть 8.66666666667, но вместо этого я получаю 8.00000000 ...

ответ

4

Здесь вы делаете целочисленное деление. Отбросьте его до float (по крайней мере, один из них) или используйте float-литералы перед делением, чтобы заставить его использовать float-деление.

Например, изменить

avg1=(num1+num2+num3)/3; 

в

avg1=(num1+num2+num3)/(float)3; // 1. cast one to float 
avg1=(num1+num2+num3)/3.0f;  // 2. use float literals 
+0

спасибо человеку ... не могу поверить, что я этого не видел !! – user3889963

+0

@ user3889963 Как программисты, мы все время слепы. : P – herohuyongtao

+0

Вместо актера используйте литерал с плавающей точкой: 'avg1 = (num1 + num2 + num3)/3.0f;' –

2

Изменить

avg1=(num1+num2+num3)/3; 

в

avg1=(float)(num1+num2+num3)/3; 

Если выполнить целочисленное деление, то результат также будет целым. Поскольку avg1 уже объявлен как float, вы можете указать результат операции для получения значения float.

+0

Это просто форматирование. Он не изменит значение. – luk32

3

Это потому, что все операнды здесь целые (num1+num2+num3)/3. Таким образом, вы получаете целочисленное деление, которое позже преобразуется в float (т. Е. После назначения, но после оценки).

Вам необходимо сделать один из операндов деления float, так что остальные будут преобразованы. И дивизия будет разделена float.

например:

(num1+num2+num3)/(float)3 
(num1+num2+num3)/3.0f 
((float)(num1+num2+num3))/3 

Следует отметить, что добавление еще целые дополнения, из-за скобки. Приятно читать правила конверсии: here.

3

Изменить этот

avg1=(num1+num2+num3)/3;

к этому

avg1=(num1+num2+num3)/(float)3;

Таким образом, вы вынуждаете разделение поплавком.

С вашим кодом вы фактически выполняете целочисленное деление, а это означает, что десятичные разряды будут отброшены. Затем результат деления присваивается числу с плавающей точкой, но десятичные разряды уже исчезли. Вот почему вам нужно отбросить по крайней мере один операнд деления на float, чтобы получить то, что вы хотите.

+2

@chux Да, '3.0' является' double'. @ G.Samaras Если вы хотите 'float', вы можете использовать' 3.0f'. – Terseus

2

Принудительное разделение быть проведенными в плавающей точке

avg1=(num1+num2+num3)/3.0f; 

Что происходит в вашем случае, вы выполняете целочисленное деление и затем преобразовать его плавать:

типа (num1+num2+num3)/3 Результирующего является целым числом, тогда как тип (num1+num2+num3)/3.0f является поплавком.

Целочисленное деление даст результат без десятичной точки.

0

Вы можете упростить код дальнейшего

float cal(int num1,int num2,int num3){ 
return ((num1+num2+num3)/3.0); 
} 

Просто измените значение 3 до 3,0, что это достаточно. потому что кастинг должен выполняться вручную, а компилятор выполняет только кастинг.

+0

Интересное предложение с тонким эффектом: это делает '(float) ((double) sum/(double))'. Был ли код «return ((num1 + num2 + num3) /3.0f);' -> '(float) sum/(float)'. Первый, как правило, более точен, а более поздний, как правило, более эффективен. IAC, это зависит от 'FLT_EVAL_METHOD' и делает незначительную разницу с целыми целыми числами OP. – chux

0

В дополнение к хорошо указанному нужно использовать деление с плавающей запятой, а не целое деление, типичный float не будет предоставлять точное число, например 8.66666666667, но только до 6 цифр. Кроме того, преобразование типичного int (32-разрядного) может привести к усечению при преобразовании в float.

Для более точного ответа с 11 цифрами на правах ., используйте double вместо float

double cal(int num1,int num2,int num3){ 
    double avg1; 
    avg1=(num1+num2+num3)/3.0; // 3 --> 3.0 
    return avg1; 
} 

int main(void){ // added void 
    int a,b,c; 
    double avg; 

    a=10; 
    b=5; 
    c=11; 

    avg=cal(a,b,c); 
    // printf("Average is : %E\n", avg); 
    printf("Average is : %.11E\n", avg); // Print to 11 digits after the dp. 
    return 0; 
}