在Borland Delphi中将float或负整数转换为十六进制

时间:2010-02-04 15:29:55

标签: delphi binary hex

我编写了一个程序,通过串行连接与某些硬件进行通信。 它以我的方式发送大量十六进制值(传感器读数),并且每隔一段时间发送一个负值。 恩。 我收到一个十六进制值:FFFFF5D6 我必须把它转换成:-2602

我遇到的另一个问题是我无法将浮点数转换为十六进制并返回。

有没有简单的方法可以做到这一点?

4 个答案:

答案 0 :(得分:2)

您可以使用足以覆盖所用浮点值的整数,然后使用ABSOLUTE关键字,将十六进制“转换”为浮点数。所有真正做的就是将值的内存编码为整数。要非常小心地使用大小完全相同的类型(可以使用SIZEOF来查找值的内存大小)。如果你需要一个奇数大小,那么绝对对一个字节数组进行循环并转换为/从每个字节转换(这将是两个字符十六进制)。

ABSOLUTE关键字强制两个变量在同一个内存地址处START,从一个写入的任何值在另一个中立即可用。

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;

这是具有奇数尺寸的浮动的例程:

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;

答案 1 :(得分:1)

要将十六进制字符串转换为整数,您可以使用StrToInt函数,也可以检查TryStrToInt函数(如果字符串不表示有效数字,则返回False)。

uses
SysUtils;

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

..
end;

对于浮点数的十六进制表示,您可以查看这些文章。

答案 2 :(得分:0)

我从未见过以十六进制表示的浮点数,因此您必须弄清楚设备正在使用的格式。对于负数情况,您需要使用HexToInt将其转换为整数,然后确定该整数是否大于表示硬件整数数据类型的MaxInt的任何阈值。如果它大于那个,它是一个负数,这意味着你需要,IIRC,得到数字的1s补码并将其转换为负数。

答案 3 :(得分:0)

如果要分隔指数和有效数字,可以使用变量记录:

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

我认为这有助于理解浮点数的结构。

使用示例:

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

输出:

 4005F7224DD2F1A9FBE7

You can calculate it back

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

使用

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

要转换i.f,我使用了binary converter