Как получить верхний и Нижний байт целого числа в C# и поместить его в массив символов для отправки в com-порт?
В C я бы сделал это
int number = 3510;
char upper = число > > 8;
char lower = число & & 8;
SendByte(верхняя часть);
SendByte(нижняя);
где верхний и Нижний оба = 54
В C# я делаю это:
int number = Convert.ToInt16("3510"); byte upper = byte(number >> 8); byte lower = byte(number & 8); char upperc = Convert.ToChar(upper); char lowerc = Convert.ToChar(lower); data = "GETDM" + upperc + lowerc; comport.Write(data);
однако в отладчике number = 3510, upper = 13 и lower = 0 это не имеет смысла, если я измените код на >> 6 upper = 54, что абсолютно странно.
в основном я просто хочу получить верхний и Нижний байт из 16-битного номера и отправить его через com-порт после "GETDM"
Как я могу это сделать? Это так просто в C, но в C# я полностью в тупике.
5 ответов
ваша маскировка неверна - вы должны маскироваться против 255 (0xff) вместо 8. Сдвиг работает с точки зрения" битов для сдвига", тогда как побитовые и/или работают против значения для маски... поэтому, если вы хотите сохранить только нижние 8 бит, вам нужна маска, которая имеет только нижние 8 бит-т. е. 255.
обратите внимание, что если вы пытаетесь разделить число на два байта, это действительно должно быть короткое или ushort для начала, а не int
(имеющего четыре байты.)
ushort number = Convert.ToUInt16("3510");
byte upper = (byte) (number >> 8);
byte lower = (byte) (number & 0xff);
обратите внимание, что я использовал ushort
здесь вместо byte
как побитовая арифметика легче думать, когда вам не нужно беспокоиться о расширении знака. На самом деле это не имеет значения в этом случае из-за того, как сужающееся преобразование в byte
работает, но это то, о чем вы должны думать.
вы, вероятно, хотите и это с 0x00FF
byte lower = Convert.ToByte(number & 0x00FF);
полный пример:
ushort number = Convert.ToUInt16("3510");
byte upper = Convert.ToByte(number >> 8);
byte lower = Convert.ToByte(number & 0x00FF);
char upperc = Convert.ToChar(upper);
char lowerc = Convert.ToChar(lower);
data = "GETDM" + upperc + lowerc;
даже если принятый ответ соответствует вопросу, я считаю его неполным из-за простого факта, что вопрос содержит int, а не короткий заголовок, и он вводит в заблуждение в результатах поиска, и, как мы знаем, Int32 в C# имеет 32 бита и, следовательно, 4 байта. Я опубликую здесь пример, который будет полезен в случае использования Int32. В случае Int32 мы есть:
- LowWordLowByte
- LowWordHighByte
- HighWordLowByte
- HighWordHighByte.
и как таковой, я создал следующий метод для преобразования значения Int32 в маленькую шестнадцатеричную строку endian, в которой каждый байт отделен от других пробелом. Это полезно, когда вы передаете данные и хотите, чтобы приемник делал обработку быстрее, он может просто разделить (" " ) и получить байты, представленные как автономные шестнадцатеричные строки.
public static String IntToLittleEndianWhitespacedHexString(int pValue, uint pSize)
{
String result = String.Empty;
pSize = pSize < 4 ? pSize : 4;
byte tmpByte = 0x00;
for (int i = 0; i < pSize; i++)
{
tmpByte = (byte)((pValue >> i * 8) & 0xFF);
result += tmpByte.ToString("X2") + " ";
}
return result.TrimEnd(' ');
}
использование:
String value1 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 4);
String value2 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 4);
String value3 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 2);
String value4 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 1);
результат:
- 7C 92 00 00
- FF FF 03 00
- 7С 92
- FF.
Если трудно понять метод, который я создал, то следующее Может быть более понятным:
public static String IntToLittleEndianWhitespacedHexString(int pValue)
{
String result = String.Empty;
byte lowWordLowByte = (byte)(pValue & 0xFF);
byte lowWordHighByte = (byte)((pValue >> 8) & 0xFF);
byte highWordLowByte = (byte)((pValue >> 16) & 0xFF);
byte highWordHighByte = (byte)((pValue >> 24) & 0xFF);
result = lowWordLowByte.ToString("X2") + " " +
lowWordHighByte.ToString("X2") + " " +
highWordLowByte.ToString("X2") + " " +
highWordHighByte.ToString("X2");
return result;
}
Примечания:
- конечно insteand uint pSize может быть перечисление, указывающее байт, слово, Двойное слово!--7-->
- вместо преобразования в шестнадцатеричную строку и создания маленькой строки endian вы можете конвертировать в символы и делать все, что хотите.
надеюсь, что это поможет кому-то!
чтобы быть немного более творческим
[System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Explicit )]
public struct IntToBytes {
[System.Runtime.InteropServices.FieldOffset(0)]
public int Int32;
[System.Runtime.InteropServices.FieldOffset(0)]
public byte First;
[System.Runtime.InteropServices.FieldOffset(1)]
public byte Second;
[System.Runtime.InteropServices.FieldOffset(2)]
public byte Third;
[System.Runtime.InteropServices.FieldOffset(3)]
public byte Fourth;
}