anti anti - 4 months ago 14
C# Question

Decoding negative numbers as float from Hexidecimal string?

I have a hexidecimal string that is number values, coming over serial from an external device. I am decoding them a block at a time using:

string tmpValue(incoming hex data, such as FE7258);

int valueInt = Convert.ToInt32(tmpValue, 16);
float XCoord = ((float)valueInt / 100);


I am able to check the output of XCoord against the device output, and when the numbers are positive, this works as expected. When they are negative, however, my results jump to incorrect.

Even using this online converter:

hex-to-decimal converter

I see that when a negative number is converted and then converted back, it is no longer the same number.

Is there a way around this? How can i deal with negative values in a hex - to - float conversion?

Answer

When working with negative numbers we actually using complement ones:

https://en.wikipedia.org/wiki/Two%27s_compleme

I.e. instead of negative -x we use

-x == ~x + 1

E.g. for -123 we have

  123     = 0000 0000 0111 1011 (binary)
 ~123     = 1111 1111 1000 0100
 ~123 + 1 = 1111 1111 1000 0101 (binary) == FF85 (Hex)

When you convert FF85 back, you have two options:

  • Treat FF85 as 2 byte signed value (and you'll get -123 back)
  • Treat FF85 as 4 byte signed value or 2 byte unsigned (and you'll get 65413)

In your case (strange 3 byte integer value)

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;
  }
}

Test:

int x = -123;

// FFFF85
string hex = ToHex(x);

// Back -123
int back = FromHex(hex); 

// -101800
Console.Write(FromHex("FE7258"));