Неправильный ответ средней функции?

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

#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...

7 ответов

Решение

Вы делаете целочисленное деление здесь. Примени это 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

Изменить это

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

к этому

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

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

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

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

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

Например:

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

Обратите внимание, что дополнения по-прежнему являются целочисленными дополнениями из-за круглых скобок. Приятно читать о правилах конвертации here,

+ Изменить

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

в

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

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

Заставить деление быть выполненным в плавающей точке

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

В вашем случае вы выполняете целочисленное деление, а затем конвертируете его в число с плавающей точкой:

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

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

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

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

Просто измените значение 3 на 3.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;
}
Другие вопросы по тегам