I have a code where type casting returns a value much different from the larger value.
static void Main(string[] args)
{
double a = 345.09;
byte c = (byte) a;
Console.WriteLine(c);
Console.ReadLine();
}
This returns the value 89
. What is the reason behind it?
You can not cast from a double to byte because the byte has a range smaller than the double and it does not contain decimals like a double does.
Type casting refers to changing an variable of one data type into another. The compiler will automatically change one type of data into another if it makes sense. For instance, if you assign an integer value to a floating-point variable, the compiler will convert the int to a float.
To typecast a double value to integer, we mention int keyword in the brackets before the decimal double value. The only downside of conversion using typecasting is that the double value is not rounded of, instead the digits after decimal are truncated. We can solve this issue by using Math.
Int to Byte Conversion in Java It means if a value is larger than the byte range, then it gets converted to negative.
what happens is that only the last 8 bits are taken when you cast the number. Let me explain with an example using ints. I use int for simplicity, because if you cast double
to a non-float number representation than the decimal places are discarded anyway.
First we look at the binary representation of the number 345:
string binaryInt = Convert.ToString(345, 2);
Console.WriteLine(binaryInt);
The output is :
1 0101 1001
When we now take only the last 8 bits, which is the size of a byte
type:
string eightLastBits = binaryInt.Substring(binaryInt.Length-8);
Console.WriteLine(eightLastBits);
We get:
0101 1001
If we convert this to byte
again you will see that the result is 89:
byte backAgain = Convert.ToByte(eightLastBits, 2);
Console.WriteLine(backAgain);
Output:
89
EDIT:
As pointed out by InBetween the int example is the real deal and what really happens during casting.
Looking at the implementation of the conversion of double to byte:
/// <internalonly/>
byte IConvertible.ToByte(IFormatProvider provider) {
return Convert.ToByte(m_value);
}
If we look at the Convert.ToByte method implementation: we see that the double if first converted to an integer:
public static byte ToByte(double value) {
return ToByte(ToInt32(value));
}
Range of byte starts from 0 to 255, you are getting result as 89 because it starts counting again from 0 once it goes beyond 255. i.e
byte c = (byte) a; //345 - 255 (consider `0` as well)
Console.WriteLine(c); // i.e. 89
The reason behind the range of byte:
byte
stores 8-bit data.0000 0000
and1111 1111
(8-bit binary data) values can be defined asMin
andMax
value tobyte
variable respectively, so in integer it turns into0
and255
Note that this is one of the few cases where the result isn't specified.
From the language spec, omitting the irrelevant cases
For a conversion from
float
ordouble
to an integral type, the processing depends on the overflow checking context (The checked and unchecked operators) in which the conversion takes place:In an unchecked context, the conversion always succeeds, and proceeds as follows.
If the value of the operand is NaN or infinite, [...]
Otherwise, the source operand is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type, [...]
Otherwise, the result of the conversion is an unspecified value of the destination type
Presumably, the implementation simply stripped off the higher bits after converting to the nearest integral value, leaving just the least significant 8 bits, since that's likely the most convenient thing to do at that point. But do note that according to this spec, 0
is just as a valid value as 89
is, for this conversion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With