Reputation: 239
I'm trying to write a code that calculates the average ages of 3 people, with the input being the ages (integers), and the output being the average (float).
But every output always rounds to be an integer rather than a float. I'm using C.
int a, b, c;
float average;
printf("Enter your ages:\n");
scanf("%d %d %d", &a, &b, &c);
average = (a + b + c)/3;
printf("\n The average age of ABC is %f", average);
Also, any advice on how to more neatly get the age inputs would be nice, is this the best way to do it?
Upvotes: 2
Views: 2742
Reputation: 12634
>>>> ...the input being the ages (integers), and the output being the average (float)...
Look at the expression:
average = (a + b + c)/3;
| |_________| |
float int integer constant
The right hand side of the expression is all int
, so the output of this expression will int
type and not float
. This expression end up assigning the int
value to a float
type variable.
To fix this problem, you should be aware of the implicit type promotion and conversion rules. From Default type promotions and conversions
If an operation involves two operands, and one of them is of type float, the other one is converted to float.
[There are few rules above this rule and it applies only when those rules doesn't]
So, in the expression (a + b + c)/3
, if we change the integer constant
to float constant
then the whole expression resultant will be of type float
.
average = (a + b + c)/3.0f;
[An unsuffixed floating constant has type double
. If suffix is the letter f
or F
, the floating constant has type float
.]
As per the type promotion rules, if you have any (or all) variable among a
, b
and c
of type float
the resultant value of the expression, with integer constant
, will be of type float
.
For example:
float a, b, c;
Or
int a, b;
float c; // Of course you don't want to do this because in your example a, b and c
// represents same thing and you want all of them to be of same type.
// This is just for the understanding.
average = (a + b + c)/3;
|____________|
|
The result of this will be of type float because at least one among a, b and c is
of type float and by the type promotion rule other will be promoted to float and
(a + b + c) will be calculated as all float type.
You can also use the type cast to solve the problem. But doing so also don't forget the type conversion rule.
For example, in the expression, you can do
either this
average = (float)(a + b + c)/3;
or this
average = (a + b + c)/(float)3;
With this, the resultant value of the expression will be of type float
because the type of one of the operand of /
operator is float
. But if you do:
average = (float)((a + b + c)/3);
you will not get the desired result because the expression (a + b + c)/3
will be calculated will all int
and result produced will be of type int
and it doesn't make any sense to type cast this after expression calculated.
>>>> Also, any advice on how to more neatly get the age inputs would be nice, is this the best way to do it?
In my opinion this is not the best way because this way the user cannot give exact age year/month/days (seems that you are taking only year as input). For practice these kind of example, this way may be okay as you are calculating average of 3
numbers but when you write some real world application where you have take age as input from user this way is not at all appropriate. Also, you are not doing any validation of the user input. The 10000000
or -50
(negative value) is not valid input for age.
Upvotes: 2
Reputation: 17678
But every output always rounds to be an integer rather than a float
All you need is this:
float average = (a + b + c)/3.0f;
Note you need 3.0f
to force the calculation to floating point. Otherwise it would only treat it as integer only (as all a,b,c
are all integer).
You can remove the initial declaration of average
and instead declare it and initialise it at the same time as above.
As pointed out by @Patrick the suffix f
here is useful as without it the calculation would be default to double
instead of float
, and there would be a redundant downcast when the assignment is occurred.
Also, any advice on how to more neatly get the age inputs would be nice, is this the best way to do it?
scanf("%d %d %d", &a, &b, &c);
Not sure if there's a best way. But that scanf
look ok for the input.
Upvotes: 7
Reputation: 5214
This is the way calculation inflect data types.
When an int
operates with an int
, the result will be still an int
too. If the result contains decimal part, it simply get discarded due to type casting to int
.
But if an int
operates with an double
or float
, the result will be with a corresponding type of double
or float
.
So what you need to do is just to make any of the operand into a decimal type. For example
average = (a + b + c) / 3.0;
or
average = (float) (a + b + c) / 3;
are both OK.
Upvotes: 2