Ben
Ben

Reputation: 1291

How to interpret byte as int?

I have a byte array recived from Cpp program.

arr[0..3] // a real32,
arr[4]    // a uint8,

How can I interpret arr[4] as int?

(uint)arr[4] // Err: can't implicitly convert string to int.
BitConverter.ToUint16(arr[4]) // Err: Invalid argument.
buff[0+4] as int // Err: must be reference or nullable type

Do I have to zero consecutive byte to interpret it as a UInt16?

OK, here is the confusion. Initially, I defined my class.

byte[] buff;
buff = getSerialBuffer();

public class Reading{
    public string scale_id;
    public string measure;
    public int measure_revised;
    public float wt;
}
rd = new Reading();
// !! here is the confusion... !!
// Err: Can't implicitly convert 'string' to 'int'
rd.measure = string.Format("{0}", buff[0 + 4]); 
// then I thought, maybe I should convert buff[4] to int first ? 
// I throw all forms of conversion here, non worked.
// but, later it turns out:
rd.measure_revised = buff[0+4]; // just ok.

So basically, I don't understand why this happens

rd.measure = string.Format("{0}", buff[0 + 4]); 
//Err: Can't implicitly convert 'string' to 'int'

If buff[4] is a byte and byte is uint8, what does it mean by can't implicitly convert string to int ?... It confuses me.

Upvotes: 3

Views: 1189

Answers (2)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

If I've understood you right you have byte (not string) array

  byte[] arr = new byte[] {
    182, 243, 157, 63,  // Real32 - C# Single or float (e.g. 1.234f)
    123                 // uInt8  - C# byte            (e.g. 123) 
  };

To get float and byte back you can try BitConverter

  // read float / single starting from 0th byte
  float realPart = BitConverter.ToSingle(arr, 0);
  byte bytePart = arr[4];

  Console.Write($"Real Part: {realPart}; Integer Part: {bytePart}");

Outcome:

  Real Part: 1.234; Integer Part: 123

Same idea (BitConverter class) if we want to encode arr:

  float realPart = 1.234f;
  byte bytePart = 123;

  byte[] arr = 
     BitConverter.GetBytes(realPart)
    .Concat(new byte[] { bytePart })
    .ToArray();

  Console.Write(string.Join(" ", arr));

Outcome:

  182 243 157 63 123

Upvotes: 4

canton7
canton7

Reputation: 42225

You were almost there. Assuming you wanted a 32-bit int from the first 4 bytes (it's hard to interpret your question):

BitConverter.ToInt32(arr, 0);

This says to take the 4 bytes from arr, starting at index 0, and turn them into a 32-bit int. (docs)

Note that BitConverter uses the endianness of the computer, so on x86/x64 this will be little-endian.

If you want to use an explicit endianness, you'll need to construct the int by hand:

int littleEndian = arr[0] | (arr[1] << 8) | (arr[2] << 16) | (arr[3] << 24);
int bigEndian = arr[3] | (arr[2] << 8) | (arr[1] << 16) | (arr[0] << 24);

If instead you wanted a 32-bit floating-point number from the first 4 bytes, see Dmitry Bychenko's answer.

Upvotes: 6

Related Questions