我编写了一个程序,通过串行连接与某些硬件进行通信。 它以我的方式发送大量十六进制值(传感器读数),并且每隔一段时间发送一个负值。 恩。 我收到一个十六进制值:FFFFF5D6 我必须把它转换成:-2602
我遇到的另一个问题是我无法将浮点数转换为十六进制并返回。
有没有简单的方法可以做到这一点?
答案 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
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。