Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit type conversion in C

I stumbled upon the following example on wikipedia (http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion).

#include <stdio.h>

int main()
{
    int i_value   = 16777217;
    float f_value = 16777217.0;
    printf("The integer is: %i\n", i_value); // 16777217
    printf("The float is:   %f\n", f_value); // 16777216.000000
    printf("Their equality: %i\n", i_value == f_value); // result is 0
}

Their explanation: "This odd behavior is caused by an implicit cast of i_value to float when it is compared with f_value; a cast which loses precision, making the values being compared different."

Isn't this wrong? If i_value were cast to float, then both would have the same loss in precision and they would be equal. So i_value must be cast to double.

like image 722
voglerr Avatar asked Nov 09 '11 23:11

voglerr


People also ask

What is implicit type conversion with example?

In implicit typecasting, the conversion involves a smaller data type to the larger type size. For example, the byte datatype implicitly typecast into short, char, int, long, float, and double. The process of converting the lower data type to that of a higher data type is referred to as Widening.

How many types of conversion are there in C?

There are two types of conversion: implicit and explicit. The term for implicit type conversion is coercion.


1 Answers

No, in the case of the equality operator, the "usual arithmetic conversions" occur, which start off:

  • 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.

This last case applies here: i_value is converted to float.

The reason that you can see an odd result from the comparison, despite this, is because of this caveat to the usual arithmetic conversions:

The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.

This is what is happening: the type of the converted i_value is still float, but in this expression your compiler is taking advantage of this latitude and representing it in greater precision than float. This is typical compiler behaviour when compiling for 387-compatible floating point, because the compiler leaves temporary values on the floating point stack, which stores floating point numbers in an 80bit extended precision format.

If your compiler is gcc, you can disable this additional precision by giving the -ffloat-store command-line option.

like image 73
caf Avatar answered Oct 05 '22 17:10

caf