Улучшение метода чтения 8-битных целых чисел со знаком из шестнадцатеричного - PullRequest
1 голос
/ 27 апреля 2010

Сценарий:

У меня есть строка шестнадцатеричных символов, которые кодируют 8-разрядные целые числа со знаком. Каждые два символа представляют байт, который использует крайний левый бит (MSB) в качестве знака (а не дополнение к двум). Я конвертирую их в подписанные числа внутри цикла и спрашиваю себя, есть ли лучший способ сделать это. Слишком много конверсий, и я уверен, что мне не хватает более эффективного метода.

Текущий код:

string strData = "FFC000407F"; // example input data, encodes: -127, -64, 0, 64, 127
int v;
for (int x = 0; x < strData.Length/2; x++)
{
    v = HexToInt(strData.Substring(x * 2, 2));
    Console.WriteLine(v); // do stuff with v
}

private int HexToInt(string _hexData)
{
    string strBinary = Convert.ToString(Convert.ToInt32(_hexData, 16), 2).PadLeft(_hexData.Length * 4, '0');
    int i = Convert.ToInt32(strBinary.Substring(1, 7), 2);
    i = (strBinary.Substring(0, 1) == "0" ? i : -i);
    return i;
}

Вопрос:

Существует ли более упрощенный и прямой подход к чтению двух шестнадцатеричных символов и преобразованию их в целое число, когда они представляют целое число со знаком (от -127 до 127), используя самый левый бит в качестве знака?

Ответы [ 3 ]

3 голосов
/ 27 апреля 2010

Просто преобразуйте его в int и обработайте знаковый бит, проверив размер преобразованного числа и скрыв знаковый бит.

private int HexToInt(string _hexData)
{
    int number = Convert.ToInt32(_hexData, 16);
    if (number >= 0x80)
       return -(number & 0x7F);
    return number;
}
1 голос
/ 27 апреля 2010
sbyte SignAndMagnitudeToTwosComplement(byte b)
{
    var isNegative = ((b & 0x80) >> 7);
    return (sbyte)((b ^ 0x7F * isNegative) + isNegative);
}

Тогда:

sbyte ReadSignAndMagnitudeByte(string hex)
{
    return SignAndMagnitudeToTwosComplement(Convert.ToByte(hex,16));
}
1 голос
/ 27 апреля 2010

Как это: (проверено)

(int)unchecked((sbyte)Convert.ToByte("FF", 16))

Пояснение:

Приведение unchecked к sbyte будет выполнять прямое приведение к байту со знаком, интерпретируя последний бит как бит знака.

Однако у него другой диапазон, поэтому он вам не поможет.

...