Converting float or negative integer to hexadecimal in Borland Delphi

前端 未结 4 2090
南旧
南旧 2021-01-23 22:51

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 s

相关标签:
4条回答
  • 2021-01-23 22:56

    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.

    0 讨论(0)
  • 2021-01-23 23:11

    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;
    
    0 讨论(0)
  • 2021-01-23 23:13

    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.

    • http://www.merlyn.demon.co.uk/pas-type.htm#Str
    • http://www.merlyn.demon.co.uk/pas-real.htm
    • http://www.merlyn.demon.co.uk/programs/hexfloat.pas (source code example)
    0 讨论(0)
  • 2021-01-23 23:13

    If you want to separate the exponent and the significand, you can use a variant record:

      TExtRec = packed record
        case Boolean of
          false:
            (AValue: Extended);
          true:
            (ASignificand: uint64; ASignExp: uint16;)
      end;
    

    I think this helps to understand the structure of the floating point number.

    Example usage:

    var
      r: TExtRec;
    begin
      r.AValue := 123.567;
      ShowMessage(IntToHex(r.ASignExp) + IntToHex(r.ASignificand));
    end;
    

    Output:

     4005F7224DD2F1A9FBE7
    

    You can calculate it back:

    v = (-1)s * 2(e-16383) * (i.f)
    

    With

    • e = $4005 = 16389 and
    • i.f = $F7224DD2F1A9FBE7
    • i.f = 1.930734374999999999954029827886614611998084001243114471435546875
    • v=123.566999999999999997057908984743335167877376079559326171875

    To convert i.f, i've used a binary converter.

    0 讨论(0)
提交回复
热议问题