Как интерпретировать байт как int? - PullRequest
3 голосов
/ 18 марта 2019

У меня есть байтовый массив , полученный из программы Cpp.

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

Как я могу интерпретировать arr[4] как 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

Нужно ли обнулять последовательный байт, чтобы интерпретировать его как UInt16?

Хорошо, здесь путаница. Изначально я определил свой класс.

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.

Так что, в принципе, я не понимаю, почему это происходит

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

Если бафф [4] - это байт, а байт - uint8, что это значит под can't implicitly convert string to int? ... Это меня смущает.

Ответы [ 2 ]

6 голосов
/ 18 марта 2019

Вы были почти там. Предполагая, что вы хотите 32-битное int из первых 4 байтов (ваш вопрос трудно интерпретировать):

BitConverter.ToInt32(arr, 0);

Это говорит о том, что нужно взять 4 байта из arr, начиная с индекса 0, и превратить их в 32-битное целое число. ( документы )

Обратите внимание, что BitConverter использует порядковый номер компьютера, поэтому на x86 / x64 это будет little-endian.

Если вы хотите использовать явный порядок байтов, вам нужно создать int вручную:

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);

Если вместо вы хотите получить 32-разрядное число с плавающей точкой из первых 4 байтов, см. Ответ Дмитрия Быченко.

4 голосов
/ 18 марта 2019

Если я вас правильно понял, у вас есть массив byte (не string)

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

Чтобы вернуть float и byte, вы можете попробовать 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}");

Результат:

  Real Part: 1.234; Integer Part: 123

Та же идея (BitConverter класс), если мы хотим кодировать arr:

  float realPart = 1.234f;
  byte bytePart = 123;

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

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

Результат:

  182 243 157 63 123
...