views:

827

answers:

3

Ive written a program that communicate with some hardware using a serial connection. It sends a lot of hexadecimal values my way (sensor readings) and every once in a while it sends a negative value. ex. i receive a hexadecimal value : FFFFF5D6 and i have to convert it into : -2602

another problem i have is that i can't convert a float into hex and back.

Are there any simple ways of doing this?

A: 

I've never seen a float represented in hex, so you'd have to figure out exactly what format the device is using for that. For the negative number case, you'll need to use HexToInt to covert it to an integer, and then determine if that integer is larger than whatever threshold value represents MaxInt for the hardware's integer data type. If it's bigger than that, it's a negative number, which means you'll need to, IIRC, get the number's 1s complement and convert it to negative.

EricLaw -MSFT-
Nice, except Delphi doesn't have HexToInt(). You can use StrToInt('$' + YourHexString) instead, though. +1 for no float represented in hex in my experience, either.
Ken White
If you have never seen a float represehted in hex, look at C99 standard, eg http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gcc/hex-floats.html
Serg
And you're saying that you know the device in quesiton is using the C99 standard?
EricLaw -MSFT-
Ah, turns out I had wrapped StrToInt64 in a function named HexToInt. This code was written half a decade ago.
EricLaw -MSFT-
+1  A: 

to convert a hex string into a integer, you can use the StrToInt Function , also you can check the TryStrToInt function (wich returns False if string does not represent a valid number).

uses
SysUtils;

var
ivalue : integer;
begin
ivalue:=StrToInt('$FFFFF5D6'); // Hexadecimal values start with a '$' in Delphi

..
end;

For the Hexadecimal representation of a float number, you can check theses articles.

RRUZ
Thanks this worked for hex to decimal but will it also work the other way around?
Makaku00
To convert an integer into a hexadecimal string, call `IntToHex`.
Rob Kennedy
A: 

You can "convert" from hex to float by using an integer large enough to cover the float value used, then using the ABSOLUTE keyword. All that is really doing is encoding the memory of the value as an integer. Be very careful to use types which are exactly the same size (you can use SIZEOF to find the memory size of a value). If you need an odd size, then absolute against an array of byte and loop through and convert to/from each byte (which would be two characters hex).

the ABSOLUTE keyword forces two variables to START at the same memory address, any value written from one is immediately available in the other.

var
  fDecimal : Double; // size = 8 bytes
  fInteger : Int64 absolute fDecimal;  // size = 8 bytes
begin
  fDecimal := 3.14;
  ShowMessage(format('%x=%f',[fInteger,fDecimal]));
  fInteger := StrToInt64('$1234123412341234');
  ShowMessage(FloatToStr(fDecimal)+'='+Format('%x',[fInteger]));
end;

here is the routine for floats with odd sizes:

var
  fDecimal : extended;
  fInteger : array[1..10] of byte absolute fDecimal;
  sHex     : string;
  iX       : integer;
begin
  ShowMessage(IntToStr(SizeOf(fDecimal))+':'+IntToStr(SizeOf(fInteger)));
  fDecimal := 3.14;
  sHex := '';
  for iX := 1 to 10 do
    sHex := sHex + IntToHex(fInteger[iX],2);
  ShowMessage(sHex);
  // clear the value
  fDecimal := 0.0;
  // Reload the value
  for iX := 1 to (Length(sHex) DIV 2) do
    fInteger[iX] := StrToInt('$'+Copy(sHex,(Ix*2)-1,2));
  ShowMessage(FloatToStr(fDecimal));
end;
skamradt