我有一个十六进制字符串,它是数字值,来自外部设备的串行。我使用以下方法一次解码一个块:
string tmpValue(incoming hex data, such as FE7258);
int valueInt = Convert.ToInt32(tmpValue, 16);
float XCoord = ((float)valueInt / 100);
我能够根据设备输出检查XCoord的输出,当数字为正时,这可以按预期工作。但是,如果它们是否定的,我的结果会跳到错误的位置。
即使使用此在线转换器:
我看到当转换负数然后转换回来时,它不再是相同的数字。
有解决方法吗?我怎样才能处理十六进制到浮点转换中的负值?
答案 0 :(得分:2)
使用负数时,我们实际上正在使用补充:
https://en.wikipedia.org/wiki/Two%27s_complement
即。而不是负-x == ~x + 1
我们使用
-123
E.g。对于 123 = 0000 0000 0111 1011 (binary)
~123 = 1111 1111 1000 0100
~123 + 1 = 1111 1111 1000 0101 (binary) == FF85 (Hex)
,我们有
FF85
当您转换FF85
时,您有两个选择:
-123
视为 2字节签名值(您将获得FF85
)65413
视为 4字节有符号值或2字节无符号(您将获得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;
}
}
)在你的情况下(奇怪的 3字节整数值)
int x = -123;
// FFFF85
string hex = ToHex(x);
// Back -123
int back = FromHex(hex);
// -101800
Console.Write(FromHex("FE7258"));
测试:
<svg width="150" height="150" baseProfile="full" version="1.2">
<defs>
<mask id="svgmask2" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" transform="scale(1)">
<image width="150" height="150" xlink:href="/website_url/FullSizeRender-150x150.jpg" />
</mask>
</defs>
<image id="the-mask" mask="url(#svgmask2)" width="150" height="150" y="0" x="0" xlink:href="/website_url/img/clippath_mask.png" />
</svg>
答案 1 :(得分:1)
如果您使用的是非标准字节大小,例如三个字节作为问题帖子,则可以使用简单的减法执行转换:
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
静态类。