So I'm currently trying to learn more about endianness and how bytes are converted to shorts, ints etc.
And I figured I'd start simple, I'd start by converting a short ("30000")
into two bytes and storing it in a MemoryStream
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
and if I understand things correctly, I start by doing some bitmasking using the bitwise AND operator &
.
0000 0000 1111 1111 &
0111 0101 0011 0000
Which would result in a byte that looks like this 0011 0000
and I would write that to the MemoryStream
. So now the MemoryStream
contains a byte array which looks like this [48]
I then write another byte, based on the same value 30000
but I bitshift the bytes to the right by 8 in order to get the left hand most 8 bits 0111 0101 (117)
and write that as a byte to the MemoryStream
. So now the byte array looks like this [48, 117]
that part seems pretty clear to me, it's the reconstructing of the short which gets me slightly confused.
How come I need to do the same bitshifting when reconstructing the short? I think that question is somewhat related to my other question which is, how does the ' ' operator convert '48' and '117' to 30000?
And how does the BitConverter.ToInt16(_stream.ToArray());
know what bytes to shift etc to output the correct value?
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255)
(_stream.ReadByte() << 8));
}
The entire program
internal class Program
{
private static MemoryStream _stream;
static void Main(string[] args)
{
Console.WriteLine(117 << 8);
_stream = new MemoryStream();
short constValue = 30000;
WriteShort(constValue);
var v = ReadShort();
/* True */
Console.WriteLine($"Is Little Endian: {BitConverter.IsLittleEndian}");
}
private static void WriteShort(short constValue)
{
_stream.WriteByte((byte)(constValue & 255));
_stream.WriteByte((byte)(constValue >> 8));
}
private static short ReadShort()
{
_stream.Position = 0;
return (short)((_stream.ReadByte() & 255)
(_stream.ReadByte() << 8));
}
}
CodePudding user response:
So you have two bytes,
0011 0000
0111 0101
Lets also zero extend both values so both are 16 bit values:
0000 0000 0011 0000
0000 0000 0111 0101
Just adding these numbers together would clearly not result in the original number. We can also see that _stream.ReadByte() & 255
does not do anything meaningful over just _stream.ReadByte()
. Shifting the last number however will result in
0000 0000 0011 0000
0111 0101 0000 0000
And we can see that adding or OR-ing these numbers together results in the original value. Note that BitConverter
does not necessarily need to do this dance, it could simply use native code to copy bytes directly. When converting larger integers to bytes you may need to consider Endianness, since integers will be represented differently depending on platform.