SS Puram, Tumkur - M.G. Road, Tumkur - PH: +91-9620160796: Implicit Conversions - Where We Can Experience Them?
SS Puram, Tumkur - M.G. Road, Tumkur - PH: +91-9620160796: Implicit Conversions - Where We Can Experience Them?
SS Puram, Tumkur - M.G. Road, Tumkur - PH: +91-9620160796: Implicit Conversions - Where We Can Experience Them?
WHAT IS A CONVERSION?
A conversion is an act of changing the nature of the data without (if possible) changing the
value. One of the most evident examples of the conversion is the change of data type . Take a look
at the snippet on the right
long data = 1;
The literal of value 1 and of type int is converted to the data of the same value but of type long. It
means that the internal representation of the subjective data may be changed (in this particular case
the number of bits used to store the value could be increased) but the value itself remains untouched.
You can avoid the conversion coding the literal in a more unequivocal way, e.g. like this:
long data = 1L;
The suffix 'L' (or 'l' both variants are fully equivalent) says that the literal is explicitly defined as long.
All possible conversions are divided into two classes:
automatic conversions which are performed somewhat behind our backs: we don't require
them but the compiler knows where they need to be applied and applies them without asking
our permission; for that reason they are also called implicit conversions
explicit conversions which are performed on developer's demand expressed using special
language means; the compiler obeys the programmer's will and converts data according to it;
this kind of conversion is often called the typecasting due to its syntax construction
Implicit conversions
IMPLICIT CONVERSIONS WHERE WE CAN EXPERIENCE THEM?
As you already know, implicit conversions may occur without your initiative. The compiler has
decided where they should be performed. Of course, we should be aware of that and need to able to
discover all the circumstances which can provoke the compiler to convert our data.
We can say that implicit conversions affect data of fundamental (basic) types and are most often
associated with the change of the internal representation. This kind of conversions happens when
you assign e.g. int to float or float to long or double to int. There are lots of other possible
combinations.
Let us enumerate some of the contexts where implicit conversions play an important (although almost
invisible) role:
a value is used as part of a complex expression built of many values of different types (see
example 1 on the right where the Short variable is converted into the int type to be
compatible with the Int variable)
a value plays a role of a logical condition within instructions like if, while, do, etc (see
example 2 where the Double variable has to be converted into int to be usable for controlling
the path of execution)
C++ - Conversion
// example no. 1
Int = Int + Short;
// example no. 2
if(Double)
Double--;
// example no. 3
Float = 1;
// example no. 4
f(Float);
// example no. 5
float g(void) {
return -1;
}
Explicit conversions
EXPLICIT CONVERSIONS HOW CAN WE INITIATE THEM?
In general, the C++ language offers two ways of specifying explicit conversions:
the so-called C-style casting (named after the C++ predecessor, the C programming language
which used, and still uses, a syntax of that kind); in this case the conversion is specified in the
following form:
(new_type_name) expression_of_old_type
the so-called functional notation which is a native C++ syntax convention, unavailable in C
(named because of its similarity to the well-known function invocation); in this case the name of a
new (target) type is treated like a function and the conversion takes the following form:
new_type_name(expression_of_old_type)
Both forms are equivalent when applied to the values of standard (basic) types but the functional
notation can also be used for the objects and in such an application it can get more than one value.
We also want to emphasize that these two options are not all of the available. We will return to this
issue when we talk about classes.
Take a look at the example code on the right It illustrates both kinds of explicit conversions.
Which one do you like more?
Oh, we forgot to mention that the program outputs '4' to the screen. You knew it without our help,
didn't you?
#include <iostream>
using namespace std;
int main(void) {
float f = 3.21;
double d = 1.23;
int k = int(f) + (int)d;
cout << k << endl;
return 0;
}
CONVERSIONS GAINS AND LOSSES.
Every time when a conversion occurs the compilers does its best to preserve the original value but it
is not always possible. We are going to show you some examples demonstrating possible gains and
losses arising from conversions.
Let's analyse some of the possibilities. We start with integral types.
A good scenario occurs when the length of the memory representation remains the same or
increases; we can be confident then that the original value will be preserved. It may be expanded
C++ - Conversion
with zero bits to fill the target memory space and the sign bit may be moved to its new position, but
the value itself will suffer no change.
In the example presented on the right the maximum value of the short type is successfully transferred
into the int variable.
The program will output equal to the screen confirming the fact that the value hasn't been changed.
#include <iostream>
using namespace std;
int main(void) {
short s = 32767;
int i = s;
if(i == s)
cout << "equal" << endl;
else
cout << "not equal" << endl;
return 0;
}
CONVERSIONS GAINS AND LOSSES.
We are going to test the worse scenario now
We want to transfer the maximum value allowed for the int variables to the short variable.
The program will output not equal to the screen. It means that the target variable wasn't able to
receive the original value.
Such an unpleasant accident is called a loss of value. We encourage you to conduct the same test
on your computer and to find the value actually assigned to the s variable.
#include <iostream>
using namespace std;
int main(void) {
int i = 2147483647;
short s = i;
if(i == s)
cout << "equal" << endl;
else
cout << "not equal" << endl;
return 0;
}
CONVERSIONS GAINS AND LOSSES.
We will do two tests for the floating point values. The test program remains nearly the same
We will convert the float value into the double value. As you know, doubles have not only wider range
that floats but also better accuracy (precision).
We expect that the conversion will be successful and both, original and target variables will store the
same value.
We're right. The program will output 'equal'.
#include <iostream>
using namespace std;
int main(void) {
float f = 1234.5678;
double d = f;
if(d == f)
cout << "equal" << endl;
else
C++ - Conversion
cout << "not equal" << endl;
return 0;
}
CONVERSIONS GAINS AND LOSSES.
As previously, we've reversed the direction of the conversion but here the range is not a problem. The
value being converted is small enough to be stored in any float variable. The issue is precision. Floats
are unable to store as many significant digits as specified in the literal assigned to the d variable.
We won't lose value. Does it mean that we'll suffer from a loss of accuracy?
The program confirms our fears. It outputs not equal to the screen.
#include <iostream>
using namespace std;
int main(void) {
double d = 123456.789012;
float f = d;
if(d == f)
cout << "equal" << endl;
else
cout << "not equal" << endl;
return 0;
}
CONVERSIONS GAINS AND LOSSES.
The example presented on the right seems to be obvious. Conversions from floating point types
into integral types always cause the loss of accuracy. There is no escape from it. The fractional part of
a float number is always lost. Be also prepared for the fact that when the float is extremely large (or
extremely small) you can also experience the loss of value. This applies to the values beyond the
scope of the target integral type.
We encourage you to compile and run the example program. The results will surprise you. We
promise you that.
#include <iostream>
using namespace std;
int main(void) {
float f = 123.456;
float g = 1e100;
int i = f;
int j = g;
cout << i << endl;
cout << j << endl;
return 0;
}
PROMOTIONS
To avoid both types of losses the compiler uses a strategy called promotion. A promotion involves
conversion of data taking part in an evaluation to the safest type. For example, when one int and
one short are used in the same expression, we can expect that the value of the narrower range
(short) will be promoted to the type with the wider range (int) and the loss of value will not occur.
Similarly, when a float meets a double in the same expression, the float will be promoted to double.
Formally, all the promotions are conducted according to the following set of rules (the rules are
applied in the order presented below until all the data used in a particular expression has the same
type - this condition is very important!):
data of type char or short int will be converted to type int (it is called an integer promotion);
C++ - Conversion
data of type float undergoes conversion to type double (floating point promotion);
if there is any value of type double in the expression, the other data will be converted to a
double;
if there is any value of type long int in the expression, the other data will be converted to long int;
If the context in which the expression is calculated requires another type than resulting from the
implicit conversions, the last conversion is done to the type requested by the context.
Knowing how the implicit conversions (sometimes called automatic) work, we will analyse the
process of calculating the value of the expression presented along with the complete program
We can predict that the following implicit conversions will take place:
promotions go first, resulting in the following conversions:
int(Short) + int(Char)
the sum of Short and Char as well as the Float variable will be converted to double, that is:
double((int(Short) + int(Char)) + double(Float))
the final sum will be calculated as a double but because of the context (arising from the type of
the left argument of the = operator) which is int, another conversion into an int type takes place;
hence, the final form of the expression looks like this:
int(double((int(Short) + int(Char)) + double(Float)))
Please, try to make some experiments yourself changing the set of variables involved in the
expression and type of the target variable. Continue the experiments until you're sure you understand
the operation of conversions.
#include <iostream>
using namespace std;
int main(void) {
int Int = 2;
char Char = 3;
short Short = 4;
float Float = 5.6;
Int = Short + Char + Float;
cout << Int << endl;
return 0;
}