For example, these variables:
result (double)
a (double)
b (float)
c (float)
d (double)
A simple calculation:
result = a * (b + c) * d
How and when are the types converted and how do I figure out what precision each calculation is performed at?
If you have:
...then an arithmetic expression like
f * d
will promote both operands to the larger type, which in this case isdouble
.So, the expression
a * (b + c) * d
evaluates to adouble
, and is then stored inresult
, which is also adouble
. This type promotion is done in order to avoid accidental precision loss.For further information, read this article about the usual arithmetic conversions.
You have to differentiate between type conversion and value conversion. The C++ standard (C as well) allows floating-point calculations to be done at extended precision.
"The values of the floating operands and 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."
As types, b + c is an addition of two float(s). The result is a float. The result is then type promoted to a double and the two multiplications are done as doubles with a result of double.
However, an implementation is allowed to do all the calculations, including b + c, using doubles (or higher precision). Indeed, I tried it out using Visual C++ and it did all the calculations using the 80-bit floating-point stack available on x86.
Following order of operations, each sub-expression is converted to the type of it's (not sure of the term here, dominant perhaps?) type. double is dominant over float, so:
All operations are done on objects of the same type (assuming normal arithmetic operations).
If you write a program that uses different types then the compiler will auto upgrade ONE parameter so that they are both the same.
In this situations floats will be upgraded to doubles:
The floats will be upconverted to doubles. Explicitly cast the values.
ie if you want double as your result you would write:
It is ALWAYS worth being explicit. It gets round misunderstandings like this and it is INSTANTLY obvious to anyone trying to use your code exactly what you mean.
In your example, all the
float
types are type-promoted todouble
when the right-side formula is evaluated.As for how they're converted: What I've read regarding floating point operations is that most contemporary hardware perform FP operations using extended-precision (80 bit) long doubles in special hardware registers (at least that's what I remember about modern Intel x86/x87 processors). As I understand it,
float
anddouble
are type-promoted IN HARDWARE via special FP instructions (someone correct me if I'm wrong).