你用什么组件发送? procedure TForm1.Button1Click(Sender: TObject); var x: single; ii:longword; s:string; begin x:=100; move(x,ii,sizeof(x)); s:=inttohex(ii,4); showmessage(s); end;
你可以先将single 转换为longword型,将longword型一个一个字节发送就行了
我用SPCOMM组件发送,现在还有问题是,实数转换成2进制浮点数(以十六进制表示),多谢帮助解决。
//十进制转换为二进制 function IntToBin(x:extended):string; var i,d,k,n:integer; dd:extended; s:string; begin /////////计算整数部分/////// d:=trunc(x); s:=''; while d>0 do begin k:=d shr 1; i:=d-(k shl 1); s:=inttostr(i)+s; d:=k; end; /////////如果有小数的话计算小数部分//////////// if HasXiaoShu(x) then //有小数 begin s:=s+'.'; n:=GetNTen(GetXiaoShuWidth(x)); d:=trunc((x-trunc(x))*n); i:=0; while (d>0)AND(i<8) do begin k:=d shl 1; if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0'; d:=k; inc(i); end; end; result:=s; end;
function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数 begin result:=false; if (x-trunc(x))>0 then result:=true; end; function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数 var i:integer; begin result:=1; for i:=1 to n do result:=result*10; end; 这是用到的两个函数
十进制和十六进制在内存中是一样的, procedure TForm1.Button1Click(Sender: TObject); var x: single; b: array[0..3] of byte; s:string; begin x:=100; move(x,b,sizeof(x));//b[3] 高字节,b[2],b[1],b[0]低字节 end;
我这有一段上次写的代码,没时间给你解释了,你自己看下应该明白的: function HexToFloat(buff:Array of byte):Single; //Single是32位浮点数类型 var P:PByte; i:Byte; begin P:=@Result; for i:=0 to Length(buff)-1 do begin P^:=buff[i]; Inc(P); end; end;
多谢指教,能把HasXiaoShu(x)这个函数给出来吗?
上面不是吗,给你贴出来了 function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数 begin result:=false; if (x-trunc(x))>0 then result:=true; end;
能把这个函数GetXiaoShuWidth(x)给出来吗,谢谢。
function GetXiaoShuWidth(x:extended):integer; //得到十进制小数部分的长度 var s:string; len:integer; begin s:=floattostr(x); len:=length(s)-pos('.',s); result:=len; end;
function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数 begin result:=false; if (x-trunc(x))>0 then result:=true; end; function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数 var i:integer; begin result:=1; for i:=1 to n do result:=result*10; end; function GetXiaoShuWidth(x:extended):integer; //得到十进制小数部分的长度 var s:string; len:integer; begin s:=floattostr(x); len:=length(s)-pos('.',s); result:=len; end;//十进制转换为二进制 function IntToBin(x:extended):string; var i,d,k,n:integer; dd:extended; s:string; begin /////////计算整数部分/////// d:=trunc(x); s:=''; while d>0 do begin k:=d shr 1; i:=d-(k shl 1); s:=inttostr(i)+s; d:=k; end; /////////如果有小数的话计算小数部分//////////// if HasXiaoShu(x) then //有小数 begin s:=s+'.'; n:=GetNTen(GetXiaoShuWidth(x)); d:=trunc((x-trunc(x))*n); i:=0; while (d>0)AND(i <8) do begin k:=d shl 1; if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0'; d:=k; inc(i); end; end; result:=s; end;procedure TForm1.Button1Click(Sender: TObject); begin showmessage(IntToBin(3.5)); end;你再试试,我这儿好着呢,十进制转二进制不管是整数还是实数都可以的
你固执的很呀, procedure TForm1.Button1Click(Sender: TObject); begin showmessage(IntToBin(3.5)); end; 3.5是不是一个实数 显示出来的结果11.1是不是一个二进制浮点数? 真气煞人也!
再给你个东西,十进制转16进制的 系统自带的那个inttohex只能够实现十进制整数到16进制的转换 使用下面给你的函数就可以想怎么转换就怎么转换了 函数我已经给你了,加不加分是你的权利,很多人看到你这点分,都很不情愿看下去的另外你说的 十进制3600变成0CE10000 如果是十进制转16进制的话,答案是肯定是错误的,因为后面那个16进制数要比3600大的多 正常答案应该是E10下面是给你的函数function GetHexfromInt(n:integer):string;//根据0-15之间的数得到对应的十六进制符号 begin case n of 0..9:result:=inttostr(n); 10:result:='A'; 11:result:='B'; 12:result:='C'; 13:result:='D'; 14:result:='E'; 15:result:='F'; end; end;function FloatToHex(x:extended):string;//十进制转换为十六进制 var d,k,i:integer; dd:extended; s:string; begin d:=trunc(x); s:=''; while d>0 do begin k:=d shr 4; i:=d-(k shl 4); s:=GetHexfromInt(i)+s; d:=k; end; /////////如果有小数的话计算小数部分//////////// if HasXiaoShu(x) then //有小数 begin s:=s+'.'; dd:=x-trunc(x); i:=0; while (dd>0)AND(i<6) do begin dd:=dd * 16; d:=trunc(dd); s:=s+GetHexfromInt(d); dd:=dd-trunc(dd); inc(i); end; end; result:=s; end;procedure TForm1.Button1Click(Sender: TObject); begin showmessage(FloatToHex(3600.88)); end;
网上找的 三字节 浮点数协议:三字节 浮点数二进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节纯小数(原码)来表示 当尾数的最高位为1时,便称为规格化浮点数,简称操作数 在程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:当[R0]=-6.000时,则二进制浮点数表示为83C000H 若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H你的可能是四字节浮点数 与 IEEE 格式不一样FUNCTION FloatToIEEEFloat(Value:SINGLE):AnsiString ; TYPE FLOATRE=RECORD CASE INTEGER OF 0: (F1:Single); 1: (I1:Integer); 2: (a1:Array[0..3]of BYTE) END; var a1:FLOATRE; C1:ShortInt; BEGINa1.F1 :=Value;C1:= ((a1.a1[3] AND $7F) SHL 1) OR (( a1.a1[2] AND $80) SHR 7) -126 ; //重新计算阶码a1.a1[2]:=a1.a1[2] OR $80; //填充尾数的最高位if c1>63 then //超过可以表示的最大数 a1.I1:=a1.I1 OR $7FFFFFFFelse if c1>=-64 then //正常范围内 a1.a1[3]:=(a1.a1[3] AND $80) OR (C1 AND $7F)else //超过可以表示的最小数if -64-c1<23 then a1.I1 :=(a1.I1 AND $80000000 )OR $40000000 OR ( (a1.I1 AND $00FFFFFF) shr (-64-c1)) else a1.I1 :=0; FloatToIEEEFloat:= IntToHex(a1.I1,8); END; procedure TForm1.Button1Click(Sender: TObject);beginMemo1.Lines.Add(FloatToIEEEFloat(5.101));end;
你的意思是不是要将十六进制的数 转换为 十六进制的字符串发送出去啊。给你个函数: function hextostring(s:string):string; var j,i: integer; s2: string; begin s2 := ''; j := trunc((Length(s)/2))-1; for i:= 0 to j do s2 := s2 + chr(strtoint('$'+(copy(s, 2*i+1, 2)))); result := s2; end;
比如single型数为4字节数据,发到单片机后接受到4个字节,至于是整型还是浮点型,与你的协议和单片机处理有关系,单片机会根据你的需要,赋值给int型,还是float型
定义
float(double) x;
x=07C80000;后x就是浮点数了
procedure TForm1.Button1Click(Sender: TObject);
var
x: single;
ii:longword;
s:string;
begin
x:=100;
move(x,ii,sizeof(x));
s:=inttohex(ii,4);
showmessage(s);
end;
function IntToBin(x:extended):string;
var
i,d,k,n:integer;
dd:extended;
s:string;
begin
/////////计算整数部分///////
d:=trunc(x);
s:='';
while d>0 do
begin
k:=d shr 1;
i:=d-(k shl 1);
s:=inttostr(i)+s;
d:=k;
end;
/////////如果有小数的话计算小数部分////////////
if HasXiaoShu(x) then //有小数
begin
s:=s+'.';
n:=GetNTen(GetXiaoShuWidth(x));
d:=trunc((x-trunc(x))*n);
i:=0;
while (d>0)AND(i<8) do
begin
k:=d shl 1;
if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0';
d:=k;
inc(i);
end;
end;
result:=s;
end;
begin
result:=false;
if (x-trunc(x))>0 then
result:=true;
end;
function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数
var
i:integer;
begin
result:=1;
for i:=1 to n do
result:=result*10;
end;
这是用到的两个函数
procedure TForm1.Button1Click(Sender: TObject);
var
x: single;
b: array[0..3] of byte;
s:string;
begin
x:=100;
move(x,b,sizeof(x));//b[3] 高字节,b[2],b[1],b[0]低字节
end;
function HexToFloat(buff:Array of byte):Single; //Single是32位浮点数类型
var
P:PByte;
i:Byte;
begin
P:=@Result;
for i:=0 to Length(buff)-1 do
begin
P^:=buff[i];
Inc(P);
end;
end;
function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数
begin
result:=false;
if (x-trunc(x))>0 then
result:=true;
end;
var
s:string;
len:integer;
begin
s:=floattostr(x);
len:=length(s)-pos('.',s);
result:=len;
end;
begin
result:=false;
if (x-trunc(x))>0 then
result:=true;
end;
function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数
var
i:integer;
begin
result:=1;
for i:=1 to n do
result:=result*10;
end; function GetXiaoShuWidth(x:extended):integer; //得到十进制小数部分的长度
var
s:string;
len:integer;
begin
s:=floattostr(x);
len:=length(s)-pos('.',s);
result:=len;
end;//十进制转换为二进制
function IntToBin(x:extended):string;
var
i,d,k,n:integer;
dd:extended;
s:string;
begin
/////////计算整数部分///////
d:=trunc(x);
s:='';
while d>0 do
begin
k:=d shr 1;
i:=d-(k shl 1);
s:=inttostr(i)+s;
d:=k;
end;
/////////如果有小数的话计算小数部分////////////
if HasXiaoShu(x) then //有小数
begin
s:=s+'.';
n:=GetNTen(GetXiaoShuWidth(x));
d:=trunc((x-trunc(x))*n);
i:=0;
while (d>0)AND(i <8) do
begin
k:=d shl 1;
if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0';
d:=k;
inc(i);
end;
end;
result:=s;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(IntToBin(3.5));
end;你再试试,我这儿好着呢,十进制转二进制不管是整数还是实数都可以的
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(IntToBin(3.5));
end;
3.5是不是一个实数
显示出来的结果11.1是不是一个二进制浮点数? 真气煞人也!
系统自带的那个inttohex只能够实现十进制整数到16进制的转换
使用下面给你的函数就可以想怎么转换就怎么转换了
函数我已经给你了,加不加分是你的权利,很多人看到你这点分,都很不情愿看下去的另外你说的
十进制3600变成0CE10000
如果是十进制转16进制的话,答案是肯定是错误的,因为后面那个16进制数要比3600大的多
正常答案应该是E10下面是给你的函数function GetHexfromInt(n:integer):string;//根据0-15之间的数得到对应的十六进制符号
begin
case n of
0..9:result:=inttostr(n);
10:result:='A';
11:result:='B';
12:result:='C';
13:result:='D';
14:result:='E';
15:result:='F';
end;
end;function FloatToHex(x:extended):string;//十进制转换为十六进制
var
d,k,i:integer;
dd:extended;
s:string;
begin
d:=trunc(x);
s:='';
while d>0 do
begin
k:=d shr 4;
i:=d-(k shl 4);
s:=GetHexfromInt(i)+s;
d:=k;
end;
/////////如果有小数的话计算小数部分////////////
if HasXiaoShu(x) then //有小数
begin
s:=s+'.';
dd:=x-trunc(x);
i:=0;
while (dd>0)AND(i<6) do
begin
dd:=dd * 16;
d:=trunc(dd);
s:=s+GetHexfromInt(d);
dd:=dd-trunc(dd);
inc(i);
end;
end;
result:=s;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(FloatToHex(3600.88));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage('0C'+FloatToHex(3600)+'000');
end;
吧,呵呵
100->07C80000
10->04A0
5.101->03A33b64
怎么办
//问到了,用户用的是MCS-51/196系列单片机,IEEE浮点数标准设计的协议。
哪为能解决,不胜感激。
测试数据是:100—>07C80000;3600—>0CE10000;5.101—>03A33B64;
999按你的单片机的算法转换的话应该是0AF9C000,没错的话应该就是我推测出来的算法了。
当尾数的最高位为1时,便称为规格化浮点数,简称操作数
在程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:当[R0]=-6.000时,则二进制浮点数表示为83C000H
若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H你的可能是四字节浮点数 与 IEEE 格式不一样FUNCTION FloatToIEEEFloat(Value:SINGLE):AnsiString ;
TYPE FLOATRE=RECORD
CASE INTEGER OF
0: (F1:Single);
1: (I1:Integer);
2: (a1:Array[0..3]of BYTE)
END;
var a1:FLOATRE; C1:ShortInt;
BEGINa1.F1 :=Value;C1:= ((a1.a1[3] AND $7F) SHL 1) OR
(( a1.a1[2] AND $80) SHR 7)
-126 ; //重新计算阶码a1.a1[2]:=a1.a1[2] OR $80; //填充尾数的最高位if c1>63 then //超过可以表示的最大数
a1.I1:=a1.I1 OR $7FFFFFFFelse if c1>=-64 then //正常范围内
a1.a1[3]:=(a1.a1[3] AND $80)
OR (C1 AND $7F)else //超过可以表示的最小数if -64-c1<23 then
a1.I1 :=(a1.I1 AND $80000000 )OR
$40000000 OR
( (a1.I1 AND $00FFFFFF) shr (-64-c1))
else a1.I1 :=0;
FloatToIEEEFloat:= IntToHex(a1.I1,8);
END;
procedure TForm1.Button1Click(Sender: TObject);beginMemo1.Lines.Add(FloatToIEEEFloat(5.101));end;
function hextostring(s:string):string;
var
j,i: integer;
s2: string;
begin
s2 := '';
j := trunc((Length(s)/2))-1;
for i:= 0 to j do
s2 := s2 + chr(strtoint('$'+(copy(s, 2*i+1, 2))));
result := s2;
end;