A char essentially contains one byte of data. Floats and ints contain four bytes.
When going from an int to a char the value might get cut off since chars can only store the values (-128,+127).
e.g. Let's take a (signed) integer, n =
1000, such that in C++ code
int n = 1000;
n is represented internally as:
1 2
|
31 30 ... 10 9 8 7 6 5 4 3 2 1 0
0 0 ... 0 1 1 1 1 1 0 1 0 0 0
|
where the top numbers represent the bit position (from left to right decreasing in significance). Bit 31 is the sign bit (0 means positive or no sign and 1 means negative). You can see through calculation that:
1 2 3 4 5 6
|
1000 = 29 (512) +
28 (256) +
27 (128) +
26 (64) +
25 (32) +
23 (8)
|
In C++, if you were to do
char c = char(n);
, what would happen is it would take the least significant byte of n and put it into c.
After the cast, c would store:
1 2
|
7 6 5 4 3 2 1 0
1 1 1 0 1 0 0 0
|
You can see that these are bits 0-7 of n. If c were to be cast back to an int, the int would store the value
-24 (because c is a
signed char storing the possible values (-128,+127) in
two's complement).
To see how we get -24 from the above binary representation, we do the following. Since there is a 1 in the most significant bit, we know the number is negative. To find the absolute value of the decimal representation, we flip the ones and zeroes:
1 2
|
7 6 5 4 3 2 1 0
0 0 0 1 0 1 1 1
|
and add 1:
1 2
|
7 6 5 4 3 2 1 0
0 0 0 1 1 0 0 0
|
which gives us the number 24, so the original two's complement number is -24.
If, on the other hand, the sign bit was
not on, i.e. if c stored the following:
1 2
|
7 6 5 4 3 2 1 0
0 1 1 0 1 0 0 0
|
which means that n would have been
872 (1000 - 128), then if c were to be cast back to an int, then the int would store the value
104. This is as expected because
1 2 3
|
104 = 26 (64) +
25 (32) +
23 (8)
|
To summarize what we have so far, if we're dealing with (signed)
char
s and (signed)
int
s:
1. Conversion from an int to a char involves putting the least significant byte into the char.
2. Conversion from a char to an int involves determining the char's decimal representation from two's complement |
From my experimentation, I've found that float values are truncated and treated as an integer if cast into a char. Therefore, c and c2 would have the same value in the code below.
1 2
|
char c = 65;
char c2 = 65.6f;
|
If c and c2 were then cast to ints, both ints would have the decimal value 65. Note that no cut-off happens if you place any number between (-128,+127) into a char. The above explains why you're getting the same values in your first example.
Floats have different binary representations (sign, exponent, mantissa), however, when casting from a char to a float, the value of the char (in two's complement) would be placed into the float just as the value of the char would be placed into an int. That is why in your second example both
i
and
f
have the same values (even though in your example you printed the characters and not the numerical values).
I would venture a guess that conversion from char to other basic data types would be the same (i.e. determine its decimal value (from two's complement) and copy that value into the variable).