If I have one variable as int, and use it for calculating other of type float, why is result shown as rounded-down float? - c

I'm doing an equation solver. The code goes like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Equation solver of type ax + by = 0, for y\n");
int a, b, x;
float y;
printf("Enter value of a as integer: ");
scanf("%d", &a);
printf("Enter value of b as integer: ");
scanf("%d", &b);
printf("Enter value of x as integer: ");
scanf("%d", &x);
y = a*x/b; //We have equation ax + by = 0, from that: ax = by, and that is: y = ax/b
printf("Solution for y of equation: %dx + %dy = 0, for x = %d, is: %.2f", a, b, x, y);
return 0;
}
When I enter a = 3, b = 5 and x = 3, the output is supposed to be 1.80, but I get 1.00. Why is this? Wouldn't expression a*x/b be converted into type of float? I'm just beginner and we only mentioned type conversion with our professor, maybe I got it wrong?

Wouldn't expression a*x/b be converted into type of float?
The result of that expression gets converted to float before being assigned to y. Since each operand has type int, the math is done with that type.
Specifically, a*x and b both have type int, so integer division is performed which truncates the fractional part.
If you cast one of the variables to type float, then floating point division will be performed.
y = (float)a*x/b;

In a*x/b all variables are ints so it's a pure integer calculation.
If you cast one of the first operands used to float, the other will also be implicitly converted to float
y = (float) a * x / b;
More about what implicit conversions there are can be found here:
Implicit conversions
Broken down according to operator precedence:
Precedence
Operator
Description
Associativity
3
* / %
Multiplication, division, and remainder
Left-to-right
14
=
Simple assignment
Right-to-left
y = a*x/b; // with a = 3, b = 5 and x = 3
According to operator precedence, a*x will be performed first and as can be read in the Usual arithmetic conversions chapter on Implicit conversions:
"The arguments of the following arithmetic operators [*, /, %, +, -, ...] undergo implicit conversions for the purpose of obtaining the common real type, which is the type in which the calculation is performed"
If "both operands are integers. Both operands undergo integer promotions". Since both a and x are int - no promotion is necessary and the common type is therefore int and the calculation is done using ints:
3 * 3 => 9
Next according to operator precedence comes the result of a*x divided by b. Again, b is an int and 9 is an int so the same procedure as above gives us int as the common type.
9 / 5 => 1
The last step according to operator precedence is the simple assignment y = 1. In the chapter "Conversion as if by assignment" we can read:
"In the assignment operator, the value of the right-hand operand is converted to the unqualified type of the left-hand operand."
This means that it's only now that the result of the calculation, 1, becomes 1.f (float)
1 => 1.f
and that's what's assigned to y.
By converting a to float, like in y = (float) a * x / b;, you can follow the rules for finding the common type and see that x will be converted to float and then b, so the calculation becomes 3.f * 3.f / 5.f and the result will be 1.8f.
If you are sure that a * x will not cause integer overflow (~produce a value that is too large or small to store in an int), you can delay the conversion until the division:
y = a * x / (float) b;
It will now do an integer multiplication and only then will the result of that multiplication be converted to float and divided by 5.f, as if done like so:
y = (float) (3 * 3) / 5.f;

Related

Integer division without changing data type [duplicate]

This question already has answers here:
Dividing 1/n always returns 0.0 [duplicate]
(3 answers)
Closed 9 years ago.
Can anyone explain why b gets rounded off here when I divide it by an integer although it's a float?
#include <stdio.h>
void main() {
int a;
float b, c, d;
a = 750;
b = a / 350;
c = 750;
d = c / 350;
printf("%.2f %.2f", b, d);
// output: 2.00 2.14
}
http://codepad.org/j1pckw0y
This is because of implicit conversion. The variables b, c, d are of float type. But the / operator sees two integers it has to divide and hence returns an integer in the result which gets implicitly converted to a float by the addition of a decimal point. If you want float divisions, try making the two operands to the / floats. Like follows.
#include <stdio.h>
int main() {
int a;
float b, c, d;
a = 750;
b = a / 350.0f;
c = 750;
d = c / 350;
printf("%.2f %.2f", b, d);
// output: 2.14 2.14
return 0;
}
Use casting of types:
int main() {
int a;
float b, c, d;
a = 750;
b = a / (float)350;
c = 750;
d = c / (float)350;
printf("%.2f %.2f", b, d);
// output: 2.14 2.14
}
This is another way to solve that:
int main() {
int a;
float b, c, d;
a = 750;
b = a / 350.0; //if you use 'a / 350' here,
//then it is a division of integers,
//so the result will be an integer
c = 750;
d = c / 350;
printf("%.2f %.2f", b, d);
// output: 2.14 2.14
}
However, in both cases you are telling the compiler that 350 is a float, and not an integer. Consequently, the result of the division will be a float, and not an integer.
"a" is an integer, when divided with integer it gives you an integer. Then it is assigned to "b" as an integer and becomes a float.
You should do it like this
b = a / 350.0;
Specifically, this is not rounding your result, it's truncating toward zero. So if you divide -3/2, you'll get -1 and not -2. Welcome to integral math! Back before CPUs could do floating point operations or the advent of math co-processors, we did everything with integral math. Even though there were libraries for floating point math, they were too expensive (in CPU instructions) for general purpose, so we used a 16 bit value for the whole portion of a number and another 16 value for the fraction.
EDIT: my answer makes me think of the classic old man saying "when I was your age..."
Chapter and verse
6.5.5 Multiplicative operators
...
6 When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.105) If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is
undefined.
105) This is often called ‘‘truncation toward zero’’.
Dividing an integer by an integer gives an integer result. 1/2 yields 0; assigning this result to a floating-point variable gives 0.0. To get a floating-point result, at least one of the operands must be a floating-point type. b = a / 350.0f; should give you the result you want.
Probably the best reason is because 0xfffffffffffffff/15 would give you a horribly wrong answer...
Dividing two integers will result in an integer (whole number) result.
You need to cast one number as a float, or add a decimal to one of the numbers, like a/350.0.

Arithmetic operation doesn't work with variable

I created this variable float avg_perc and performed some arithmetic operation to find average percentage. The output is unexpected i.e. 0 for any value of marks1, mark2, marks3.
#include <stdio.h>
int main(){
int marks1, marks2, marks3;
printf("Enter your marks in all 3 subjects : ");
scanf("%d %d %d", &marks1, &marks2, &marks3);
float avg_perc = ((marks1+marks2+marks3)/300)*100; //problem part
printf("%f \n", avg_perc);
if(avg_perc>=40 &&marks1>=33 && marks2>=33 && marks3>=33){
printf("Pass.");
}
else{
printf("Fail.");
}
return 0;
}
It doesn't really matter that you have float avg_perc = ... for storing the result, because that type does not affect the type used for the calculations.
In C, every operand and integer constant in an expression has a type. And depending on the types of the operands, each operation is carried out on a specific type which then also becomes the resulting type of the (sub) expression.
In this case the types are as indicated by the comment below:
float avg_perc = ((marks1 + marks2 + marks3) / 300) * 100;
// float int + int + int / int * int
Operator precedence determines which operands that belong to which operator. In this case the () parenthesis has the highest precedence, then * and /, then + and finally =.
The subexpression (marks1 + marks2 + marks3) will get all calculations carried out on int type since all involved operands of + are int. Then the result of that will form a new expression "result / 300" where 300 is int. Again, calculation is carried out on int. And then finally the same thing with * 100.
When all the above calculations have been carried out on int, then the assignment happens last of all, since = has the lowest precedence. During assignment, there is a special conversion rule stating that the value of the right operand is is converted to the type of the left operand. So this conversion of the result to float happens last, when all of the other calculations have already been carried out on int.
In your code
((marks1+marks2+marks3)/300)*100;
is integer arithmetic. You need to ensure at least one of the participating arguments are floating point (or casted to a float or double) in order to ensure floating point arithmetic. Something like
(((float)marks1+marks2+marks3)/300)*100;
You need to make the divisor a type of double by appending .0 into it to avoid the integer division and this was exactly the reason you were having this strange issue.
Change:
(marks1 + marks2 + marks3) / 300
into:
(marks1 + marks2 + marks3) / 300.0
Note that if you put a floating point prefix, for instance 300.0f then you'll see a miscalculation. For example, you get 30.000002 after inputting 30 30 30 in the program.

A newbie question about operations with integers and floating-points in C

I'm a C language newbie. Just trying to figure out why one code example from the textbook "Absolute Beginner's Guide to C, 3rd Edition" works like that:
// Two sets of equivalent variables, with one set
// floating-point and the other integer
float a = 19.0;
float b = 5.0;
float floatAnswer;
int x = 19;
int y = 5;
int intAnswer;
// Using two float variables creates an answer of 3.8
floatAnswer = a / b;
printf("%.1f divided by %.1f equals %.1f\n", a, b, floatAnswer);
floatAnswer = x /y; //Take 2 creates an answer of 3.0
printf("%d divided by %d equals %.1f\n", x, y, floatAnswer);
// This will also be 3, as it truncates and doesn't round up
intAnswer = a / b;
printf("%.1f divided by %.1f equals %d\n", a, b, intAnswer);
The second output is not understandable to me. We take integers so why is there a floating-point "3.0"?
The third output is not clear too. Why is there 3 when we take floating-point numbers like 19.0 and 5.0?
Pls help
In the second example, the right-hand side (RHS) of the assignment is evaluated first: this is a division of two integers, so it is performed as such (an integer operation), and the result is 3; this is then converted to a float, in order to fulfil the assignment, and the conversion from an integral 3 cannot have any fractional part. However, the left-hand side is a float and, in the printf format, you are explicitly asking for 1 decimal place in the output - even though that is (and must be) zero.
In the third example, the RHS is evaluated as a floating-point division, which will (as you suspect) give an interim value of 3.8; however, when this is then converted to an int, in order to fulfil the assignmment, the fractional part (.8) is lost, as an integer cannot have any fractional component. Conversion from a floating-point type to an integer will always truncate (discard) any fractional part, so even converting 1.999999999 will give a value of 1.
When you divide x/y you get the integer 3 because it performs integer division. When you assign that to floatAnswer, the integer is automatically converted to the equivalent float value, which is 3.0.
printf("%.1f divided by %.1f equals %d\n", a, b, intAnswer);
a/b becomes 19.0/5.0 which is 3.8 and is reported that way.
Looking at the second case, we have:
floatanswer = x/y
floatanswer = 19/5
floatanswer = 3
printf( 3.0 )
You can see that the integers experience integer division before they are assigned to float answer. That means the printf of float-answer isn't your problem, it's the integer division which happens before floatanswer is ever assigned the value.
Second case.
In the second case you assign the result of the int operation to a float.
int a = 19;
int b = 5;
float floatAnswer = a/b;
In that last line you assign an int to a float, which is implicitely casted. But the division operation was done using integer arithmetic. The cast is the last step (when it is assigned).
So basically, that's equivalent to
float floatAnswer = 3;
which is doing the same as,
float floatAnswer = (float)3;
Note the (float). That means that the value 3 is being casted (converted) to float.
Third case.
In the third case you assign the result of 19.0/5.0 to an int,
float a = 19.0;
float b = 5.0;
int intAnswer = a/b;
This implicitly casts the value to an int, and casting float to int is being done by truncating.
In this case this would be equivalent to
int intAnswer = 3.8;
Which is doing the same as,
int intAnswer = (int)3.8;
the (int) means that the value is casted (converted) to an int type.
You can image as below:
floatAnswer = x /y;
From right to left, the program will calculate:
temp = x/y: because x and y; they are integer, so temp = 3.
floatAnswer = temp, now temp = 3, so floatAnswer = 3
intAnswer = a / b;
From right to left:
temp = a/b will be 3.8
intAnswer = temp, but intAnswer is integer, so temp is cast to 3
2nd case: As I see, you have defined floatanswer as a float variable, that why It is returning decimal value.
3rd case: Because You have defined intAnswer as integer, that's why it is returning interfere value

What is difference between F = (9/5 * C) + 32 and F = (C *9/5) + 32 ? Precedence? [duplicate]

This question already has answers here:
Issue with fahrenheit conversion formula in C [duplicate]
(3 answers)
Closed 3 years ago.
F = (C * 9/5 ) + 32 and F = (9/5 * C) + 32 yield two different results although the input for C is the same. I realize that there is some kind of precedence in operators but i am not sure about it. Does multiplication come before division ?
An input of 20 gives the Fahrenheit value as 68(correct one) in the first case and 52 in the second.
#include<stdio.h>
int main()
{
float cel , fahr ;
printf("Enter the temperature(C): ");
scanf("%f",&cel);
fahr = (9/5 * celt is ) + 32;
printf("\nThe temperature in fahranheit is %f ",fahr);
}
Expected result is 68 but its 52 for the above code. If I switch the position of '9/5' and 'cel' it gives the correct result. Why is that ?
Multiplication and division have equal precedence in C, and left-to-right associativity. So,
F = (C * 9/5 ) + 32 is equivalent to F = ((C * 9)/5) + 32
F = (9/5 * C) + 32 is equivalent to F = ((9/5) * C) + 32
The two expressions would be algebraically equivalent, except for the fact that C defines int / int = int, discarding the remainder. So, 9/5 is not 1.8 as you might have expected, but 1.
To get a floating-point result from dividing two ints, you need to convert at least one of the operands to float or double. So instead of 9/5, write:
9.0/5.0, 9.0/5, 9/5.0, or 1.8, which gives you a double, or
9.0f/5.0f, 9.0f/5, 9/5.0f, or 1.8f, which gives you a float
Yes, precedence (and integer arithmetic).
They're evaluated like this:
F = ((C * 9)/5 ) + 32;
vs.
F = ((9/5) * C) + 32;
The way C does integer arithmetic (it truncates integers towards zero) makes the second incorrect (9/5 is one).
Instead, use 9.f, 5.f, and 32.f. That way, precedence won't change much (and you'll get correct results).
This expression
C * 9/5
is evaluated form left to right because the used operators have the same precedence.
So, it is evaluated like
( C * 9 ) / 5
Each time when a sub-expression is evaluated the compiler determines the common type of the used operands.
The common type of the sub-expression
C * 9
is float according to the usual arithmetic conversions. So the result of this sub-expression has the type float and the result of the whole expression
( C * 9 ) / 5
is correspondingly has the type float.
This expression
9/5 * C
is evaluated like
(9/5) * C
As the both operands of the sub-expression
9/5
are integers then there is used the integer arithmetic and the result of the sub-expression is also integer.
To avoid the dependence of the order of operands you could for example write
(9.f/5) * C
or
(9/5.0f) * C
In this case the sub-expressions
8.0f/5
and
8/5.0f
are evaluated as an expression with float numbers.
Besides the precedence problem, the result of 9/5 is 1. It would work more like expected if it were written
9.0/5 or
9/5.0 or
9.0/5.0 or (even)
1.8

Dividing integers in C rounds the value down / gives zero as a result

I'm trying to do some arithmetic on integers. The problem is when I'm trying to do division to get a double as a result, the result is always 0.00000000000000000000, even though this is obviously not true for something like ((7 * 207) / 6790). I have tried type-casting the formulas, but I still get the same result.
What am I doing wrong and how can I fix it?
int o12 = 7, o21 = 207, numTokens = 6790;
double e11 = ((o12 * o21) / numTokens);
printf(".%20lf", e11); // prints 0.00000000000000000000
Regardless of the actual values, the following holds:
int / int = int
The output will not be cast to a non-int type automatically.
So the output will be floored to an int when doing division.
What you want to do is force any of these to happen:
double / int = double
float / int = float
int / double = double
int / float = float
The above involves an automatic widening conversion - note that only one needs to be a floating point value.
You can do this by either:
Putting a (double) or (float) before one of your values to cast it to the corresponding type or
Changing one or more of the variables to double or float
Note that a cast like (double)(int / int) will not work, as this first does the integer division (which returns an int, and thus floors the value) and only then casts the result to double (this will be the same as simply trying to assign it to a double without any casting, as you've done).
It is certainly true for an expression such as ((7 * 207) / 6790) that the result is 0, or 0.0 if you think in double.
The expression only has integers, so it will be computed as an integer multiplication followed by an integer division.
You need to cast to a floating-point type to change that, e.g. ((7 * 207) / 6790.0).
Many poeple seem to expect the right-hand side of an assignment to be automatically "adjusted" by the type of the target variable: this is not how it works. The result is converted, but that doesn't affect any "inner" operations in the right-hand expression. In your code:
e11 = ((o12 * o21) / numTokens);
All of o12, o21 and numTokens are integer, so that expression is evaluated as integer, then converted to floating-point since e11 is double.
This like doing
const double a_quarter = 1 / 4;
this is just a simpler case of the same problem: the expression is evaluated first, then the result (the integer 0) is converted to double and stored. That's how the language works.
The fix is to cast:
e11 = ((o12 * o21) / (double) numTokens);
You must cast these numbers to double before division. When you perform division on int the result is also an integer rounded towards zero, e.g. 1 / 2 == 0, but 1.0 / 2.0 == 0.5.
If the operands are integer, C will perform integer arithmetic. That is, 1/4 == 0. However, if you force an operand to be double, then the arithmetic will take fractional parts into account. So:
int a = 1;
int b = 4;
double c = 1.0
double d = a/b; // d == 0.0
double e = c/b; // e == 0.25
double f = (double)a/b; // f == 0.25

Resources