2

Section 1.3 of Kernighan and Ritchie uses the following temperature conversion program to introduce For statements:

#include <stdio.h>

/* print Fahrenheit-Celsius table */

int main(){

        int fahr;
        for (fahr = 0; fahr <= 300; fahr = fahr + 20)
            printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

What it doesn't explain is how this program can make use of an int variable to produce float values without an error. What makes this valid? Don't all the variables in an equation have to be of the same type? I'm hesitant to move forward without understanding this.

  • Please google search or search here itself. I believe this question has plenty of dupes already with sufficient exaplanations.... – Sourav Ghosh Jan 07 '16 at 17:20
  • In a word, no. They do not have to be of the same type. Implicit type conversions can take place. – Joel Cornett Jan 07 '16 at 17:21
  • 1
    The language allows a lot of implicit conversions. See http://en.cppreference.com/w/cpp/language/implicit_cast. – R Sahu Jan 07 '16 at 17:25
  • 2
    The K&R book explains type conversion quite early on, I seem to recall it even includes a table of how implicit conversion happens. With that info, you should be able to work it out yourself – Elias Van Ootegem Jan 07 '16 at 17:37

4 Answers4

4

The conversion are implicit, but enabling warnings should give you a message explaining that int is being converted to double.

Here (5.0/9.0)*(fahr-32)), a double is being multiplied by an int, and the int is converted to double using usual arithmetic conversions.

The types in arithmetic don't necessarily have to match. C has a whole chapter dedicated to conversions: 6.3 Conversions, 6.3.1 Arithmetic operands.

2501
  • 25,460
  • 4
  • 47
  • 87
0

Actually it doesn't: (5.0/9.0)*(fahr-32) is an expression of type double, not a float.

The reason being that 5.0 and 9.0 are double literals and the (fahr - 32) is promoted to that type before the multiplication takes place.

If you really want a float then use (5.0f/9.0f)*(fahr-32). Note the suffixed f on the numbers (and you will need to suffix both).

%f is an appropriate format specifier in printf for a double and a float, so there are no problems there.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

In an arithmetic expression, if two operands are of different types (such as int and double), the operand with the lower precision will be converted to the same type as the operand with the higher precision. The exact rules can be found in section 6.3.1.8 of the online C 2011 standard.

Note that this only applies for arithmetic (integer and floating-point) types, not for pointer or aggregate types.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Detail: "operand with the lower precision will be converted" is better as "operand with the lower rank will be converted". With `double` (precision typically ~53 bits) and `long long`, the `long long` (precision typically ~63 bits) is converted to `double`, even though it has high precision. – chux - Reinstate Monica Jan 07 '16 at 17:56
  • @chux: yeah, "precision" wasn't the best term to use, but I couldn't think of a better one that didn't require a footnote that was longer than the actual answer. – John Bode Jan 07 '16 at 17:58
  • True that "precision" is a decent approximation. Could use [rank](http://stackoverflow.com/a/5563131/2410359) – chux - Reinstate Monica Jan 07 '16 at 18:09
0

The reason an int can be promoted to a double without a problem -- assuming int represents a 32-bit integer and double represents a 64-bit IEEE floating point number, which is common -- is that a double has 53 bits of precision, so it has no trouble representing a 32-bit integer without loss. Any warning would just be informational and not a cause for concern, unlike when a 32-bit integer is coerced to a float, which only has 24 bits of precision and thus could lose up to eight bits (seven for a signed int) of precision in the cast.

John Sensebe
  • 1,386
  • 8
  • 11