3

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.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Ben
  • 1,133
  • 1
  • 15
  • 30
  • 3
    `(uint)arr[4] // Err: can't implicitly convert string to int.` This seems strange... What is the type of `arr`? – xanatos Mar 18 '19 at 09:22
  • You seem to be confused as to whether you want a 32-bit int or a 16-bit int. `int` and `uint` (`Int32` and `UInt32`) are 4 bytes (32 bits). `short` and `ushort` (`Int16` and `UInt16`) are 2 bytes (16 bits). – canton7 Mar 18 '19 at 09:23
  • 1
    sorry, its arr is a byte array. I want a uin8 which doesn't exist in C# ... so I just want to arr[4] to be used as an int . – Ben Mar 18 '19 at 09:23
  • `uint8` exists and is callend `byte`. You can cast a `byte` to `int`/`uint` without any problem. So `(uint)arr[4] // Err: can't implicitly convert string to int.` will work. – xanatos Mar 18 '19 at 09:25
  • 2
    If `arr` was a `byte[]` then the first conversion `(uint)arr[4]` would work. (*Work* in the sense that it wouldn't cause the given error message) – Dirk Mar 18 '19 at 09:26
  • @xanatos, how can I use it as a int ? – Ben Mar 18 '19 at 09:28
  • Please show the declaration of `arr` from your code, because there is a discrepancy between what you're telling us and what the error message is telling us. – Matthew Watson Mar 18 '19 at 09:34

2 Answers2

6

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.

canton7
  • 37,633
  • 3
  • 64
  • 77
4

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
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215