Why do we separately cast to "float" in an integer division? - c

For example:
int number1 = 1, number2= 2;
float variable = (float)number1/(float)number2;
Instead of this, Why can't we use "float" only once? For example:
int number1 = 1, number2= 2;
float variable = (float)(number1/number2);

The objective is to avoid the truncation that comes with integer division. This requires that at least one of the operands of the division be a floating point number. Thus you only need one cast to float, but in the right place. For example,
float variable = number1/(float)number2; // denominator is float
or
float variable = ((float)number1)/number2; // numerator is float
Note that in the second example, one extra set of parentheses has been added for clarity, but due to precedence rules, it is the same as
float variable = (float)number1/number2; // numerator is float, same as above
Also note that in your second example,
float variable = (float)(number1/number2);
the cast to float is applied after the integer division, so this does not avoid truncation. Since the result of the expression is assigned to a float anyway, it is the exact of
float variable = number1/number2;

You can write either expression, but you get different results.
With float variable = (float)(number1 / number2); the value in variable is 0, because the division is done as integer division, and 1/2 is 0, and the result is converted.
With float variable = (float)number1 / (float)number2;, the value in variable is 0.5, because the division is done as floating point division.
Either one of the casts in float variable = (float)number1 / (float)number2; can be omitted and the result is the same; the other operand is converted from int to float before the division occurs.

Since number1 and number2 are ints, the division performed will be integral division. Thus, number1/number2 will evaluate to the int 0. To do floating point arithmetic instead, you need to cast them. Note that simply casting one will suffice, since the other one will be implicitly promoted. So, you can just say ((float)number1)/number2.

In the First case,
1/2 results 0
In the second case, you can use float once, but it has to be applied with one of the numbers before division
1.0/2.0 or 1.0/2 or 1/2.0 results 0.5

Related

Can a int value added to a float value?

/**Program for internal typecasting of the compiler**/
#include<stdio.h>
int main(void)
{
float b = 0;
// The Second operand is a integer value which gets added to first operand
// which is of float type. Will the second operand be typecasted to float?
b = (float)15/2 + 15/2;
printf("b is %f\n",b);
return 0;
}
OUTPUT : b is 14.500000
Yes, an integral value can be added to a float value.
The basic math operations (+, -, *, /), when given an operand of type float and int, the int is converted to float first.
So 15.0f + 2 will convert 2 to float (i.e. to 2.0f) and the result is 17.0f.
In your expression (float)15/2 + 15/2, since / has higher precedence than +, the effect will the same as computing ((float)15/2) + (15/2).
(float)15/2 explicitly converts 15 to float and therefore implicitly converts 2 to float, yielding the final result of division as 7.5f.
However, 15/2 does an integer division, so produces the result 7 (there is no implicit conversion to float here).
Since (float)15/2 has been computed as a float, the value 7 is then converted to float before addition. The result will therefore be 14.5f.
Note: floating point types are also characterised by finite precision and rounding error that affects operations. I've ignored that in the above (and it is unlikely to have a notable effect with the particular example anyway).
Note 2: Old versions of C (before the C89/90 standard) actually converted float operands to double in expressions (and therefore had to convert values of type double back to float, when storing the result in a variable of type float). Thankfully the C89/90 standard fixed that.
Rule of thumb: When doing an arithmetic calculation between two different built-in types, the "smaller" type will be converted into the "larger" type.
double > float > long long(C99) > long > short > char.
b = (float)15/2 + 15/2;
Here the first part, (float)15/2 is equivalent to 15.0f / 2. Because an operation involving a "larger" type and a "smaller" type will yield a result in the "larger" type, (float)15/2 is 7.500000, or 7.5f.
When it comes to 15/2, since both operands are integers, the operation is done only on integer level. Therefore the decimal point is stripped (from int), and only gives 7 as a result.
So the expression is calculated into
b = 7.5f + 7;
No doubt you'll have 14.500000 as the final result, because it's exactly 14.5f.
b = (float)15/2 + 15/2;
The first one((float)15/2) will work fine. The second one will also work but will be converted into an integer first, so you will lose precision. Like:
b = (float)15/2 + 15/2;
b = 7.500000f + 7
b = 14.500000
It's worth asking: if an integer value could not be added to floating-point value, what would the symptom be?
Compiler issues error or warning message.
Something gets truncated; you don't get the result you want.
Undefined behavior: you might or might not get the result you want, and the compiler might or might not warn you about it.
But in fact none of these things happen. When you add an integer to a floating-point value, the compiler automatically converts the integer to a floating-point value so it can do the addition that way, and this is perfectly well defined. For example, if you have the code
double d = 7.5;
int i = 7;
double result = d + i;
the compiler interprets this just as if you had written
double result = d + (double)i;
And it works this way for just about all operations: the same logic is applied when you subtract, multiply, or divide a floating-point value and an integer.
And it works this way for just about all types. If you add a long int and an int, the plain int automatically gets converted to a long.
As a general rule (and I really can't think of too many exceptions), the compiler always wants to do arithmetic on two values of the same type. So whenever you have two values of different type, the compiler will just about always convert one of them for you. The full set of rules for how it does this are rather elaborate, but they're all supposed to make sense, and do what you want. The full set of rules is called the usual arithmetic conversions, and if you do a Google search on that phrase you'll find lots of explanations.
One case that does not necessarily do what you want is when the two variables are not different types. In particular, if the two variables are both integers, and the operation you're doing is division, the compiler doesn't have to convert anything: it divides the integer by the integer, discarding any remainder, and gives you an integer result. So if you have
int i = 1;
int j = 2;
int k = i / j;
then k ends up containing 0. And if you have
double d = i / j;
then d ends up containing 0 also, because the compiler follows exactly the same rules when performing the division; it doesn't "peek outside" to see that it's going to need a floating-point result.
P.S. I said, "As a general rule, the compiler always wants to do arithmetic on two values of the same type", and I said I couldn't think of too many exceptions. But if you're curious, two exceptions are the << and >> operators. If you have x << y, where x is a long int and y is a plain int, the compiler does not have to convert y to a long int first.

C don't get the right result

I need the result of this variable in a program, but I don't understand why I can't get the right result.
double r = pow((3/2), 2) * 0.0001;
printf("%f", r);
The problem is integer division, where the fractional part (remainder) is discarded
Try:
double r = pow((3.0/2.0), 2) * 0.0001;
The first argument of the pow() expects a double. Because the ratio: 3/2 uses integer values, the result passed to the argument is 1. By changing to float values, the result of the division can retain the fractional part, and the result becomes 1.5, the form expected by the function.
(3/2) involves two integers, so it's integer division, with the result 1. What you want is floating point (double) division, so coerce the division to use doubles by writing it as (3.0/2.0)

Trying to print answer to equation and getting zero in C.

printf("Percent decrease: ");
printf("%.2f", (float)((orgChar-codeChar)/orgChar));
I'm using this statement to print some results to my command console, however, I end up with zero. Putting the equation into another variable doesn't work either.
orgChar = 91 and codeChar = 13, how do I print out this equation?
Integer division will lead to result 0 here and you are type casting the result later to float so eventually you will end up with 0
Make any one of the variables float before division
(orgChar-codeChar)/(float)orgChar
As others have mentioned, the subtraction and division are done using integer math before the cast to (float). By that point, the integer division has a truncated result of 0. Instead:
// (float)((orgChar-codeChar)/orgChar)
((float) orgChar - codeChar)/orgChar
// or
(orgChar - codeChar)/ (float) orgChar
As the float argument gets converted to double as part of the "usual argument promotion" of arguments to a variadic function like printf(), might as well do
printf("%.2f", (orgChar-codeChar)/ (double) orgChar);
Casting, in general, should be avoided. Some casts unintentionally narrow the operation. If unsigned is 32-bit and a1 is uint64_t, then a1 was narrowed before the shift and unexpected results may occur. If a1 was a char, it is nicely converted without trouble to an unsigned.
The second method of *1u will not narrow. It will insure a2*1u is at least the width of an unsigned.
unsigned sh1 = (unsigned) a1 >> b1; // avoid
unsigned sh2 = a2*1u >> b2; // better
So recommend, rather than (float) or (double), use the idiom of multiplying by 1.
printf("%.2f", (orgChar - codeChar) * 1.0 / orgChar);
you don't need to typecast the whole expression. you can simply type cast either the numerator or the denominator to get the float result with precision of 2 decimal places.
for eg:
here in this code defining a variable c as float doesnt guarantee the result to be float.for getting the precise result you need to typecast either the numerator or denominator.
You shouldn't need to cast to float at all. Simply make sure both variables are of type float or double before attempting to print them as floats. This means either declaring the variables as floats, or using the correct function, such as atof () when converting the data to floats (normally this is done when you get the data from the command-line or a file.)
This should work...
#include <stdio.h>
int
main (void)
{
float orgChar = 91;
float codeChar = 13;
printf ("%.2f\n", (orgChar - codeChar) / orgChar);
return 0;
}

Average of an array displays correctly only if casted to float

So I have a pretty noobish question. Although I declare the average as a float, when I calculate it avg = sum / counter;, where counter is the number of elements bigger than 0 in an array, and then print it, I get only 0s after the decimal point.
However if I calculate it by casting to a float, avg = (float) sum/counter;, the average is printed out correctly.
Shouldn't the first one be correct? If I declare a variable as a float, why should I cast it later to a float again?
When you declare
int sum;
int counter;
...
then sum / counter performs an integer division, resulting in an integer value. You can still assign that result to a float variable, but the value will remain the integer part only.
To solve this, you need to cast either sum or counter to a float - only then you are getting the float value also as a result:
float result = (float) sum / counter;
This is, by the way, the same as ((float) sum) / counter - means, the cast as you wrote it applies to sum.
The cast as you wrote it applies to sum, not to avg, the result you obtain is perfectly normal if sum is an integer type.
The operator / applied to two integers performs integer division. The operator / applied to two floating point values performs floating point division. If one value is floating point, the other is promoted to floating point. But if both are integer, integer division is performed.
Later, the result of this operation, which already exists in memory, is assigned to another variable. But that is another story. You need to get the correct result in the first place, and then you can assign it to a variable which will store it.
The problem is sum is of type integer so it rounds of to 0's after the decimal point.It does not automatically type cast.So either declare sum as float or manually type cast the result as float

casting integer division into double in C

Why does the code
double slope = (double)changeY/changeZ
set slope to 0.0, when in the program I have, changeX = 20 and changeY = 10 (both ints)?
It sounds like you are using the wrong variable. Try this:
int changeX = 20;
int changeY = 10;
double slope = (double)changeY/changeX;
The cast operator () has higher priority than /. This expression will get evaluated as:
Cast changeY to a double.
Implicitly convert changeX to a double. If one operand is double, then the other operand gets balanced to a double as well (this is formally called "the usual arithmetic conversions").
Divide the two operands. The result will be a double.
Store this temporary "result-double" into another double called slope.

Resources