How can I convert a numerical value (e.g. float
, short
, int
, ...) to several byte
values without having to allocate memory on the heap for an array, like System.BitConverter.GetBytes
does?
Something like this:
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
//demo code, just to show which results I need
var bytes = System.BitConverter.GetBytes(input);
byte0 = bytes[0];
byte1 = bytes[1];
}
Note: I'm restricted to .NET Framework 4.8 and therefore (I think) C# 7.3.
CodePudding user response:
Just cast and shift?
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
byte0 = (byte)input;
byte1 = (byte)(input >> 8);
}
Note that you can simply reverse the order for different endianness.
Note that if you are using a "checked" context, you would need to mask too:
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
byte0 = (byte)(input & 0xFF);
byte1 = (byte)((input >> 8) & 0xFF);
}
(in an unchecked context, the cast to byte
is sufficient by itself - additional bits are discarded)
CodePudding user response:
If you are allowed to use unsafe code, then for non-integral value types (such as float
, double
and decimal
) the fastest way is to use a pointer.
For example, for a double
:
double x = 123.456;
unsafe
{
byte* p = (byte*) &x;
// Doubles have 8 bytes.
byte b0 = *p ;
byte b1 = *p ;
byte b2 = *p ;
byte b3 = *p ;
byte b4 = *p ;
byte b5 = *p ;
byte b6 = *p ;
byte b7 = *p;
}
You should be able see how to modify this for other types.
For integral types such as short
, int
and long
you could use the approach given in the other answer from Mark Gravell - but you can also use the pointer approach above for integral types.
IMPORTANT: When using the pointer approach, endianness is significant! The order in which the bytes are assigned is the order in which they are stored in memory, which can differ by processor architecture.