Float and int comparision - c

In below program, i didnt understand how float and int value are same.
int main()
{
int a=3;
float b=3.0;
if(a==b)
{
printf("A is equal to b");
}
else{
printf("A is not euql to b");
}
}
The output of the program is "A is equal to b"

if(a==b) does not compare types, it compares values.
As #Kerrek SB commented, the value(s) are converted to a common type.
Each a and b go though "usual arithmetic conversions" before the comparison.
... the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type. The use of evaluation formats is characterized by the implementation-defined value of FLT_EVAL_METHOD: C11dr §5.2.4.2.2 9
Conversion to floating point is to float, double or long double depending on FLT_EVAL_METHOD.
Assuming conversion to float...:
Otherwise, if the corresponding real type of either operand is float, the other operand is converted, without change of type domain, to a type whose
corresponding real type is float. §6.3.1.8 1
So a converts to a float with the value of 3.0 before the comparison.
Since the values compare the same, they pass the if(a==b).
Note: Conversion can cause issues as not all int may covert exactly to a float.

Actually the int value will be typecasted to float and then the if condition is evaluated.

Related

Why is an addition of a float and int results a float?

I'm currently reading "The C Programming Language - 2nd Edition". In the first chapter, it is explained that an operation of an float with an int results an int. There is this program:
#include <stdio.h>
int main()
{
float fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
fahr = lower;
while (fahr <= upper)
{
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f\t%6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
When the line fahr = fahr + step is executed, shouldn't fahr become an int ? Does it stays a float because I was declared as a float ?
Yes, if you declared your variable as a float, it won't change in your code. If you do an operation between an int and a float and put on a float variable, you will have a float result, and the opposite is true, if you put your variable in a int var, you will lose the decimal part of your number.
You can't change your variable type in C.
If the book said that, it is wrong. Simple as that!
When you add an integer to a float, you get a float. Furthermore, you assigned the result to a float, so it can't be anything else. Objects don't change type.
Since you declare fahr as a float, any value you assign to it will be converted to float.
Any arithmetic operation between an int and a float will have a float result. This is specified as part of the usual arithmetic conversions:
6.3.1.8 Usual arithmetic conversions
1 Many operators that expect operands of arithmetic type cause conversions and yield result
types in a similar way. The purpose is to determine a common real type for the operands
and result. For the specified operands, each operand is converted, without change of type
domain, to a type whose corresponding real type is the common real type. Unless
explicitly stated otherwise, the common real type is also the corresponding real type of
the result, whose type domain is the type domain of the operands if they are the same,
and complex otherwise. This pattern is called the usual arithmetic conversions:
First, if the corresponding real type of either operand is long double, the other
operand is converted, without change of type domain, to a type whose corresponding real type is long double.
Otherwise, if the corresponding real type of either operand is double, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is double.
Otherwise, if the corresponding real type of either operand is float, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is float.62)
Otherwise, the integer promotions are performed on both operands. Then the
following rules are applied to the promoted operands:
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank is
converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
Otherwise, if the type of the operand with signed integer type can represent
all of the values of the type of the operand with unsigned integer type, then
the operand with unsigned integer type is converted to the type of the
operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
62) For example, addition of a double _Complex and a float entails just the conversion of the
float operand to double (and yields a double _Complex result).
C 2011 Online Draft
An arithmetic operation between two ints will yield an int result. For example, 1/2 yields 0, 4/3 yields 1, 7/3 yields 2, etc. If you assign the result of an integer division to a float variable, it will be stored as a float, but you don't get the fractional portion of the result. IOW, given code like
float fahr = 4 / 3;
printf( "%f\n", fahr );
your output will be 1.0, not 1.33333. If you want a floating-point result, at least one of the operands must be a floating-point type:
float fahr = 4 / 3.0f;
printf( "%f\n", fahr );
will output 1.33333.
+1 For reading that book.
C chooses the highest resolution on arithmic, so float wins in your case.

Why does float divided by an integer return a float

I am learning C.
I was wondering why you get a float, even if one of your variables is an int.
float x = 5.0;
int y = 2;
float result = x / y;
My guess would be that result would be 2.00000. But it does return a float (2.500000)
I think it would be 2.000000 because if you divide 2 ints that is the result. And I would think that if you use an int and a float it would pick the least precise value.
Because of C's Usual arithmetic conversions.
Quoting the ANSI C standard § 3.2.1.5 Usual arithmetic conversions:
Many binary operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions: First, if either operand has type long double, the other operand is converted to long double . [...] Otherwise, if either operand has type float, the other operand is converted to float.
Emphasis mine.
The operator / only performs integer division if both operands are integers.
And I would think that if you use an int and a float it would pick the least precise value.
That's exactly the opposite; the general rule is that before performing any arithmetic operation both operands are promoted to the "most powerful" type of the two involved in the operation.
The "most powerful" type is determined according to the rules that the standard calls "Usual arithmetic conversions" (C99, §6.3.1.8), which essentially say that
long double > double > float > all integral types; if an expression involves only integral types, some other rules kick in that are a bit more lengthy to describe (at §6.3.1.1).
Now, in your case you have an int and a float, the "best" type is float and thus the int is promoted to float before performing the division.
If one of the operands in you division is a float and the other one is a whole number (int, long, etc), your result's gonna be floating-point.
This means, this will be a floating-point division: if you divide 5 by 2, you get 2.5 as expected.
First of all, result is a float, so it can hold decimal values.
Secondly, one of the operands x, and y is a float, so the returned value is a float. This holds for addition, multiplication and subtraction also.
The result of the code is a float and therefore it will produce a float. When you devide an int by anf int it will return 2.5 but the result being an int truncates the result to be 2

Typecasting integers as doubles to get a double result from divison of the typecasted integers

I do not understand the underlying reason the output is a double between the following examples. In terms of:
Why does a double divided by an int result in a double?
Why does a int divided by a double result in a double?
#include <stdio.h>
int main(int agrc, char **argv)
{
double d;
int a=5,b=2;
d = (double)a/b;
printf("d= %G\n",d); // outputs 2.5
d = a/(double)b;
printf("d= %G\n",d); // outputs 2.5
}
From the C standard, section 6.3.1.8: Usual arithmetic conversions:
First, if the corresponding real type of either operand is long double,
the other operand is converted, without change of type domain, to a
type whose corresponding real type is long double.
Otherwise, if the corresponding real type of either operand is double, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is double.
Otherwise, if the corresponding real type of either operand is float,
the other operand is converted, without change of type domain, to a
type whose corresponding real type is float.
Otherwise, the integer promotions are performed on both operands.
So if one operand to an arithmetic operator is int and the other is double, the standard states that the resulting expression has type double.
The cast has precedence over the division, and an operation between a double and an int will produce a double
Due to necessities in the evaluation, if one of the operands of a division is a double data type, the other is automatically promoted to that for means of calculation. In your example this happens because the operator precedence for an explicit cast is higher then for a divison.
If you want to only cast the result of the division, you can do:
d = (double)(a/b);
To ensure the integer division is performed first, and the explicit cast to double is performed second.
For additional context of #dbush 's excellent answer, it is important to note that the standard specifies that for all arithmetic type conversions containing differing types, that conversion is from the smaller of two types to the largest:
Summarized from C11 - 6.3.1.8 Usual arithmetic conversions:
1st: if real type of either operand is long double, the other is
converted to long double
2nd: Otherwise if real type of either
operand is double, the other is converted to double
3rd: Otherwise
if real type of either operand is float, the other is converted to
float
And it goes on to specify how integer promotions are made in similar fashion...

adding Variables of different types in C

float + (short)long = ?
I am adding these types and based on my calculation I am getting a float as an answer but the right answer is double.
can anyone give me an example of how it becomes double or explanation..
Operators that take two arithmetic operands in C always require both operands to be of the same type. If they aren't, then one or both are converted according to the usual arithmetic conversions, which are fully described in section 6.3.1.8 of the C standard (the link is to a draft of the 2011 standard).
Briefly:
If either operand is of type long double, the other is converted to long double.
Otherwise, if either operand is of type double, the other is converted to `double.
Otherwise, if either operand is of type float, the other is converted to float.
This is followed by a set of rules for two operands of integer type, which don't apply in this case.
If you need a double result, you need to convert one or both operands to double. If you convert just one of them, it will cause the other to be converted as well. (You might want to convert both just to be explicit.)
For example, if you have:
float f;
long n;
double x = f + n;
then the result of the addition is float, which is converted to double only after the addition is performed. To do a double multiplication, change the last line to:
double x = (double)f + (double)n;
On the other hand, if you want a double result, it's very likely that your float operand should have been declared as a double in the first place. double is in some sense the "default" floating-point type in C (it's the type of unsuffixed literals like 1.0, for example). float is used mostly when it's important to save memory space, such as when you have very large arrays. On many systems, float arithmetic isn't even any faster than double arithmetic (though I'm not 100% sure on that last point).
try to do:
float F;
short L;
double res = (double)(F + L);

Implicit types for numbers in C

What are the implicit types for numbers in C? If, for example, I have a decimal number in a calculation, is the decimal always treated as a double? If I have a non-decimal number, is it always treated as an int? What if my non-decimal number is larger than an int value?
I'm curious because this affects type conversion and promotion. For instance, if I have the following calculation:
float a = 1.0 / 25;
Is 1.0 treated as a double and 25 treated as an int? Is 25 then promoted to a double, the calculation performed at double precision and then the result converted to a float?
What about:
double b = 1 + 2147483649; // note that the number is larger than an int value
If the number has neither a decimal point nor an exponent, it is an integer of some sort; by default, an int.
If the number has a decimal point or an exponent, it is a floating point number of some sort; by default, a double.
That's about it. You can append suffixes to numbers (such as ULL for unsigned long long) to specify the type more precisely. Otherwise (simplifying a little), integers are the smallest int type (of type int or longer) that will hold the value.
In your examples, the code is:
float a = 1.0 / 25;
double b = 1 + 2147483649;
The value of a is calculated by noting that 1.0 is a double and 25 is an integer. When processing the division, the int is converted to a double, the calculation is performed (producing a double), and the result is then coerced into a float for assignment to a. All of this can be done by the compiler, so the result will be pre-computed.
Similarly, on a system with 32-bit int, the value 214783649 is too big to be an int, so it will be treated as a signed type bigger than int (either long or long long); the 1 is added (yielding the same type), and then that value is converted to a double. Again, it is all done at compile time.
These computations are governed by the same rules as other computations in C.
The type rules for integer constants are detailed in §6.4.4.1 Integer constants of ISO/IEC 9899:1999. There's a table which details the types depending on the suffix (if any) and the type of constant (decimal vs octal or hexadecimal). For decimal constants, the value is always a signed integer; for octal or hexadecimal constants, the type can be signed or unsigned as required, and as soon as the value fits. Thanks to Daniel Fischer for pointing out my mistake.
http://en.wikipedia.org/wiki/Type_conversion
The standard has a general guideline for what you can expect but compilers have a superset of rules that encompass the standard as well as rules for optimizing. The above link discusses some of the the generalities you can expect. If you are concerned about the implicit coercion it is typically good practice to use explicit casting.
Keep in mind that the size of the primitive types is not guaranteed.
1.0 / 25
Evaluates to a double because one of the operands is a double. If you changed it to 1/25 the evaluation is performed as two integers and evaluates to 0.
double b = 1 + 2147483649;
The right side is evaluated as an integer and then coerced to a double during assignment.
actually. in your example you may get a compiler warning. You'd either write 1.0f to make it a float to start with, or explicitly cast your result before assigning it.

Resources