0

I'm practically new to C programming and I've been trying to get a simple average function right, but the fractional part of the answer keeps messing up...??

#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;
}

The answer (avg) should be 8.66666666667, but instead I get 8.00000000...

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
user3889963
  • 477
  • 3
  • 6
  • 17

7 Answers7

4

You're doing integer division here. Cast it to float (at least one of them) or use float literals before division to force it to use float division.

For example, change

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

to

avg1=(num1+num2+num3)/(float)3;  // 1. cast one to float
avg1=(num1+num2+num3)/3.0f;      // 2. use float literals
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
3

It is because all operands are integer in here (num1+num2+num3)/3. So you get an integer division, that is later cast to a float (i.e. upon the assignment, but after the evaluation).

You need to make one of the division operands a float, so the rest will be converted. And the division will be a float division.

E.g:

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

Note that the additions are still integer additions, because of parentheses. A nice read on the conversion rules is here.

luk32
  • 15,812
  • 38
  • 62
3

Change this

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

to this

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

That way you force a division by a float.

With your code you actually perform integer division, which means that the decimal digits get discarded. Then the result of the division is assigned to a float number, but the decimal digits are already gone. That's why you need to cast at least one operand of the division to a float, in order to get what you want.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
2

Change

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

to

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

If you perform integer division then result will also be integer. As avg1 is already declared as float, you can cast the result of the operation to get float value.

ani627
  • 5,578
  • 8
  • 39
  • 45
2

Force the division to be perfomed in floating point

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

What happens in your case is, you perform the an integer division and then convert it to float:

Resulting type of (num1+num2+num3)/3 is an integer, while the type of (num1+num2+num3)/3.0f is a float.

Integer division will give the result without the decimal point.

2501
  • 25,460
  • 4
  • 47
  • 87
0

You can simplify your code further

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

Just change the value 3 to 3.0 that's enough. because the up-casting has to be made manually the compiler only perform the down-casting.

Manjunath N
  • 1,365
  • 11
  • 22
  • Interesting suggestion with a subtle effect: This does a `(float) ((double) sum/(double))`. Had code been `return ((num1+num2+num3)/3.0f);` --> `(float) sum/(float)`. The first is typically more accurate while the later typically more efficient. IAC, it does depend on `FLT_EVAL_METHOD` and makes insignificant difference with OP's sample integers. – chux - Reinstate Monica Oct 24 '14 at 15:13
0

In addition to the well pointed out need to use floating point division rather than integer division, typical float will not provide a precise number like 8.66666666667 but only to 6 or so digits. Further, conversion of typical int (32-bit) may result in truncation when converting to float.

For a more precise answer with 11 digits to the rights of ., use double instead of 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;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256