Implicit typecasting from double to int? - c

// Assuming these definitions
int x;
float y;
What is the difference between this:
x = y = 7.5;
and this:
y = x = 7.5;
How come the first one prints y value as 7.5,
and second one prints y as 7.00?

The explanation is very simple: = is right to left associative, which means x = y = 7.5; is evaluated as x = (y = 7.5); hence essentially the same as:
y = 7.5; // value is converted from double to float, y receives 7.5F
x = y; // value of y is converted from float to int, x receives 7 (truncated toward 0)
Whereas y = x = 7.5; is evaluated as y = (x = 7.5);:
x = 7.5; // 7.5 is converted to int, x receives value 7 (truncated toward 0)
y = x; // value of x is converted to float, y receives 7.0F
These implicit conversions can be counter intuitive. You might want to increase the warning level to let the compiler warn you about potential mistakes and unwanted side effects.

An assignment chain like you show, is evaluated from right to left.
x = y = 7.5;
is the same as
x = (y = 7.5);
Furthermore the result of an assignment is the assigned value.
This means that 7.5 (type double) is implicitely cast to float and then assigned to y. The result (7.5f) is then assigned to x. During this assignment the value is cast to int and the result is 7 which is stored in x.
If you switch the order you get different types:
y = x = 7.5;
Now 7.5 (type double) is implicitely cast to int and then assigned to x. The result is 7 which is assigned to y. Now that value is cast to double but the fraction is already lost and you will get 7.0f being stored in y.

In second expression
y = x = 7.5; /* multiple assignment operator. R->L associativity */
x = 7.5 evaluates first and you are assigning a real floating value 7.5 to an integer x which leads to truncation of fractional part, hence x gets assigned with 7 instead of 7.5 and later on y gets assigned with 7.00000
From the C99 Standard section 6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an
integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value
of the integral part cannot be represented by the integer type,
the behavior is undefined.

Related

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

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;

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

typecasting long to int and short in C

long x = <some value>
int y = <some value>
I want to subtract y from x , which of the following will give me different or same results
x = (int)x - y;
x = x-y
x = short(x) - short(y)
The type long is "bigger" than int. Smaller types can be automatically casted to bigger types. So, this code:
someLongNumber + someIntNumber
is basically equal to
someLongNumber + (long)someIntNumber
So the output will be long. You don't have to cast if you want to place the result in x. However, if you want to place it in y, you must cast the x operand to int ((int)x), or the whole operation ((int)(x - y)).

why cast when the conversion is implicit?

I see some code in c like this
int main()
{
int x = 4, y = 6;
long z = (long) x + y;
}
what is the benefit of casting even though in this case it implicit? Which operation comes first x + y or casting x first?
In this case the cast can serve a purpose. If you wrote
int x = 4, y = 6;
long z = x + y;
the addition would be performed on int values, and then, afterwards, the sum would be converted to long. So the addition might overflow. In this case, casting one operand causes the addition to be performed using long values, lessening the chance of overflow.
(Obviously in the case of 4 and 6 it's not going to overflow anyway.)
In answer to your second question, when you write
long z = (long)x + y;
the cast is definitely applied first, and that's important. If, on the other hand, you wrote
long z = (long)(x + y);
the cast would be applied after the addition (and it would be too late, because the addition would have already been performed on ints).
Similarly, if you write
float f = x / y;
or even
float f = (float)(x / y);
the division will be performed on int values, and will discard the remainder, and f will end up containing 0. But if you write
float f = (float)x / y;
the division will be performed using floating-point, and f will receive 0.666666.

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