将负数解码为十六进制字符串中的浮点值
本文关键字:字符串 十六进制 解码 | 更新日期: 2023-09-27 17:59:39
我有一个十六进制字符串,它是数值,来自外部设备的串行。我正在使用一次解码一个块
string tmpValue(incoming hex data, such as FE7258);
int valueInt = Convert.ToInt32(tmpValue, 16);
float XCoord = ((float)valueInt / 100);
我能够根据设备输出检查XCoord的输出,当数字为正数时,这可以正常工作。然而,当它们为负数时,我的结果就会跳到错误的地方。
即使使用这个在线转换器:
十六进制到十进制转换器
我看到,当一个负数被转换,然后又被转换回来时,它就不再是同一个数字了。
有办法绕过这个吗?如何处理十六进制到浮点转换中的负值?
当使用负数时,我们实际上使用的是补码ones:
https://en.wikipedia.org/wiki/Two%27s_complement
也就是说,我们使用而不是负-x
-x == ~x + 1
例如,对于-123
,我们有
123 = 0000 0000 0111 1011 (binary)
~123 = 1111 1111 1000 0100
~123 + 1 = 1111 1111 1000 0101 (binary) == FF85 (Hex)
当您将FF85
转换回时,您有两个选项:
- 将
FF85
视为2字节有符号值(您将取回-123
) - 将
FF85
视为4字节有符号值或2字节无符号(您将得到65413
)
在您的情况下(奇怪的3字节整数值)
private static String ToHex(int value) {
return (value & 0xFFFFFF).ToString("X6");
}
private static int FromHex(String value) {
int v = Convert.ToInt32(value, 16);
unchecked {
return (v <= 0x7FFFFF) ? v : v | (int)0xFF000000;
}
}
测试:
int x = -123;
// FFFF85
string hex = ToHex(x);
// Back -123
int back = FromHex(hex);
// -101800
Console.Write(FromHex("FE7258"));
如果您使用非标准的字节大小,例如三个字节作为问题帖子,您可以通过简单的减法执行转换:
public static int ThreeByteHexToSignedInt(string hex)
{
var val = Int32.Parse(hex, System.Globalization.NumberStyles.AllowHexSpecifier);
if(val > 0xEFFFFF) // If greater than maximum postive 3 byte int
{
val = val - 0xFFFFFF - 1; // take the compliment
}
return val;
}
例如:
ThreeByteHexToSignedInt("000001"); // Returns 1
ThreeByteHexToSignedInt("FFFFFF"); // Returns -1
ThreeByteHexToSignedInt("FE7258"); // Returns -101800
ThreeByteHexToSignedInt("00FFFE"); // Returns 65534
对于float/double,您可以只获取此操作的结果并执行直接强制转换,或者使用Convert
静态类。