情境:
我有一串十六进制字符,它们编码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;
}
问题:
当使用最左边的位作为符号表示有符号的int(-127到127)时,是否有更简化和直接的方法来读取两个十六进制字符并将它们转换为int?
答案 0 :(得分:3)
只需将其转换为int并通过测试转换后的数字的大小并屏蔽符号位来处理符号位。
private int HexToInt(string _hexData)
{
int number = Convert.ToInt32(_hexData, 16);
if (number >= 0x80)
return -(number & 0x7F);
return number;
}
答案 1 :(得分:1)
像这样:(经过测试)
(int)unchecked((sbyte)Convert.ToByte("FF", 16))
unchecked
强制转换为sbyte
将执行直接转换为有符号字节,将最后一位解释为符号位。
但是,它有不同的范围,所以它对你没有帮助。
答案 2 :(得分:1)
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));
}