Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does type casting work from double to byte

Tags:

c#

.net

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?

like image 504
Ankit Shah Avatar asked May 25 '21 06:05

Ankit Shah


People also ask

Can you cast double to byte?

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.

How does type cast work?

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.

How can you use type casting to convert a double type to an int type?

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.

What does casting an int to a byte do?

Int to Byte Conversion in Java It means if a value is larger than the byte range, then it gets converted to negative.


3 Answers

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));
}
like image 144
Mong Zhu Avatar answered Oct 26 '22 15:10

Mong Zhu


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 and 1111 1111 (8-bit binary data) values can be defined as Min and Max value to byte variable respectively, so in integer it turns into 0 and 255

like image 33
Prasad Telkikar Avatar answered Oct 26 '22 17:10

Prasad Telkikar


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 or double 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.

like image 2
Sweeper Avatar answered Oct 26 '22 17:10

Sweeper