In Steven Prata\'s book \"C Primer Plus\", there\'s a section on Type Conversions, wherein \"The basic rules are\" section has stated in rule 1:
Under K&R C,
Yes you can rely on C to promote floats to doubles when evaluated.
708 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.
I'm using the documentation found here.
Sorry, I cited the wrong thing earlier
Look at the entire rule:
When appearing in an expression,
char
andshort
, bothsigned
andunsigned
, are automatically converted toint
or, if necessary, tounsigned int
. (Ifshort
is the same size asint
,unsigned short
is larger thanint
; in that case,unsigned short
is converted tounsigned int
.) Under K&R C, but not under current C,float
is automatically converted todouble
. Because they are conversions to larger types, they are called promotions.
If we consider the integer types, when they appear in e.g. arithmetic expressions, they are still promoted, so no arithmetic is -theoretically - performed at the types char
or short
, but all at type int
, unsigned int
or a type with higher conversion rank (under the as-if rule, if the implementation can guarantee that the result is the same as if the promotion were actually carried out, it can perform arithmetic at smaller types if the platform provides the instructions).
The analogous used to hold for float
, under the old pre-standard rules, float
s were promoted to double
for all arithmetic etc.
That is no longer the case, arithmetic on float
s does not involve automatic promotion under standardised C.
In expressions with mixed types, generally everything is still promoted to the largest involved type, so if you compare or add a float
to a double
, the float
is converted to double
before the operation.
It must refer to the result of binary arithmetic operations of float * float
format. In the pre-standard versions of C operands of such expressions were promoted to double
and the result had double
type.
For example, here's a quote from "C Reference Manual"
If both operands are int or char, the result is int. If both are float or double, the result is double.
In C89/90 already this behavior was changed and float * float
expressions produce float
result.
- If either operand has type long double, the other operand is converted to long double
- Otherwise, if either operand is double, the other operand is converted to double.
- Otherwise, if either operand is float, the other operand is converted to float.
Yes, there are difference versions of C, just as there are different versions of most software products.
K&R is the original version as described by Brian Kernighan and Dennis Ritchie in their book The C Programming Language.
The first standardized version was ANSI C, or C89 and there have been a couple of new versions since then. "Current C" can either mean C11 (the latest version) or C99 (probably the most usad version today).
The C language definition has been standardized and modified several times over the years. The original (non-standardized) version of C is known as "K&R C"; it's the language Kernighan and Ritchie originally developed.
In 1989, ANSI created an official standards document (adopted in 1990 by ISO) to define the language, and in that standard some things were changed and extended; one of the changes is that the automatic promotion from float
to double
was removed.
Since then, there have been two revisions to the standard, one in 1999 and one in 2011.
I'm trying understand if I have an expression that mixes floats and doubles, can I rely on C to promote floats to doubles when it's evaluated?
Here's the rule from the current standard:
6.3.1.8 Usual arithmetic conversions
...
First, if the corresponding real type of either operand islong double
, the other operand is converted, without change of type domain, to a type whose corresponding real type islong double
.
Otherwise, if the corresponding real type of either operand isdouble
, the other operand is converted, without change of type domain, to a type whose corresponding real type isdouble
.
Otherwise, if the corresponding real type of either operand isfloat
, the other operand is converted, without change of type domain, to a type whose corresponding real type isfloat
.62)
62) For example, addition of adouble _Complex
and afloat
entails just the conversion of thefloat
operand todouble
(and yields adouble _Complex
result).
So basically, if you have an expression with two different types, the operand with the narrower/less precise type will be promoted to the type of the operand with the wider/more precise type.