| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 610 人关注过本帖, 1 人收藏
标题:关于浮点数转换的问题,请大侠指教
只看楼主 加入收藏
Pgwyg
Rank: 2
等 级:论坛游民
帖 子:28
专家分:20
注 册:2022-6-10
结帖率:100%
收藏(1)
已结贴  问题点数:20 回复次数:11 
关于浮点数转换的问题,请大侠指教
本人使用VFP做上位机开发了一个远程抄表程序,终端设备使用 MODBUS RTU 协议,数据为浮点型,于是编写了一个10进制与16进制浮点型数据转换函数,但是转换结果不知正确与否,例如,10进制数22.5转换16进制浮点数为41B46660,而这个16进制数在还原回去为22.5499877929687500,不知道是否正确,请大侠指点。
附两个函数,不打包了,直接复制粘贴到VFP即可使用。


*浮点型数据十进制转换十六进制浮点型数据
*依据IEEE-754标准
*八位HEX数据转换成32位二进制数据后从高位至低位分为3个部分
*S-第1位,符号位,0为正数,1为负数
*E-第2至9位,指数位,浮点的位置,数值减去127所得
*M-第10至32位,数据位,由整数和小数组成
*函数名:FDX_DECTOHEX
*用法:FDX_DECTOHEX(浮点数值) &&数值型,返回字符型
Function FDX_DECtoHEX
LPARAMETER DEC_SJ

*1-判别符号+/-S
IF DEC_SJ>0
    S="0"
ELSE
    S="1"
    DEC_SJ=ABS(DEC_SJ)
ENDIF

*分解数据为整数和小数
*整数部分
SJ1=INT(DEC_SJ)
*小数部分
SJ2=DEC_SJ-SJ1

*整数部分转二进制,除2取余
FOR I=1 TO 32
     X1=SJ1/2
    X2="ZS"+ALLTRIM(STR(I))
    &X2=SJ1%2
    SJ1=INT(X1)
    IF SJ1=0
        EXIT
    ENDIF
ENDFOR
X2=I
X3=I
X4=""
FOR I=1 TO X2
    X5="ZS"+ALLTRIM(STR(X3))
    X4=X4+ALLTRIM(STR(&X5))
    X3=X3-1
ENDFOR
ZSBF=X4
X2=""
*小数部分转二进制,乘2取整
FOR I=1 TO 16
    X1="XS"+ALLTRIM(STR(I))
    SJ2=SJ2*2
    X2=X2+ALLTRIM(STR(INT(SJ2)))   
    IF SJ2>0
        SJ2=SJ2-INT(SJ2)
    ENDIF
ENDFOR   
XSBF=X2
M=SUBSTR(ZSBF,2)+XSBF

*计算指数E
E1=LEN(ZSBF)-1+127
SJ1=E1
FOR I=1 TO 32
     X1=SJ1/2
    X2="ZS"+ALLTRIM(STR(I))
    &X2=SJ1%2
    SJ1=INT(X1)
    IF SJ1=0
        EXIT
    ENDIF
ENDFOR

X2=I
X3=I
X4=""
FOR I=1 TO X2
    X5="ZS"+ALLTRIM(STR(X3))
    X4=X4+ALLTRIM(STR(&X5))
    X3=X3-1
ENDFOR
E=X4

M=SUBSTR(ZSBF,2)+XSBF
M=PADR(M,23,"0")
FDSJ2=S+E+M
FDSJ16=""
XX=1

*二进制转十六进制
FOR I=1 TO 8
    SJ16=SUBSTR(FDSJ2,XX,4)
    DO CASE
    CASE SJ16="0000"
        FDSJ16S="0"
    CASE SJ16="0001"
        FDSJ16S="1"
    CASE SJ16="0010"
        FDSJ16S="2"
    CASE SJ16="0011"
        FDSJ16S="3"
    CASE SJ16="0100"
        FDSJ16S="4"
    CASE SJ16="0101"
        FDSJ16S="5"
    CASE SJ16="0110"
        FDSJ16S="6"
    CASE SJ16="0111"
        FDSJ16S="7"
    CASE SJ16="1000"
        FDSJ16S="8"
    CASE SJ16="1001"
        FDSJ16S="9"
    CASE SJ16="1010"
        FDSJ16S="A"
    CASE SJ16="1011"
        FDSJ16S="B"
    CASE SJ16="1100"
        FDSJ16S="C"
    CASE SJ16="1101"
        FDSJ16S="D"
    CASE SJ16="1110"
        FDSJ16S="E"
    CASE SJ16="1111"
        FDSJ16S="F"
    ENDCASE
    FDSJ16=FDSJ16+    FDSJ16S
    XX=XX+4
ENDFOR

*返回计算结果
RETURN FDSJ16
ENDFUNC

*****************************************************
*函数名:FDX_HEXTODEC
*用法:FDX_HECTODEC("8位16进制数") &&字符型,返回数值型

Function FDX_HEXTODEC

LPARAMETER HEX_SJ
FDSJ=0
B1=LEN(ALLTRIM(HEX_SJ))

IF B1 <>8
RETURN FDSJ
ENDIF
HEX_SJ=UPPER(HEX_SJ)
* 16进制转换2进制

HEX_SJ_2=""
FOR i=1 TO b1
    f_x1=SUBSTR(HEX_SJ,i,1)
    DO CASE
        CASE f_x1="0"
        x="0000"
        CASE f_x1="1"
        x="0001"
        CASE f_x1="2"
        x="0010"
        CASE f_x1="3"
        x="0011"
        CASE f_x1="4"
        x="0100"
        CASE f_x1="5"
        x="0101"
        CASE f_x1="6"
        x="0110"
        CASE f_x1="7"
        x="0111"
        CASE f_x1="8"
        x="1000"
        CASE f_x1="9"
        x="1001"
        CASE f_x1="A"
        x="1010"
        CASE f_x1="B"
        x="1011"
        CASE f_x1="C"
        x="1100"
        CASE f_x1="D"
        x="1101"
        CASE f_x1="E"
        x="1110"
        CASE f_x1="F"
        x="1111"
    ENDCASE
    HEX_SJ_2=HEX_SJ_2+x
ENDFOR

SJ=SUBSTR(HEX_SJ_2,10)&&符号位,0为正数
DW=SUBSTR(HEX_SJ_2,2,8)&&指数位,小数点位置
FH=VAL(SUBSTR(HEX_SJ_2,1,1))&&数据位
*计算指数
a0=0
a1=DW
a2=LEN(a1)
FOR i=0 TO a2-1
    a3=SUBSTR(a1,a2-i,1)
    a4=VAL(a3)*2^i
    a0=a0+a4
ENDFOR
ZS=A0-127

*计算数据
a0=0
a1=SJ
a2=LEN(a1)
X=0
FOR i=1 TO a2
    x=X-1
    a3=SUBSTR(a1,i,1)
    a4=VAL(a3)*2^x
    a0=a0+a4

ENDFOR

FDSJ=(-1^FH)*(1+A0)*2^ZS
RETURN FDSJ
ENDFUNC
***************************************************************************************
搜索更多相关主题的帖子: 数据 STR 进制 CASE FOR 
2023-08-27 15:26
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:647
专家分:2502
注 册:2018-3-13
收藏
得分:5 
何苦要自己发明轮子

cc = BinToC(22.5,'fr')
? 0h+cc
? CToBin(cc,'nr')

这家伙很懒,啥也没留下
2023-08-27 16:02
iswith
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:5
帖 子:343
专家分:500
注 册:2013-5-14
收藏
得分:5 
以下是引用csyx在2023-8-27 16:02:28的发言:

何苦要自己发明轮子

cc = BinToC(22.5,'fr')
? 0h+cc
? CToBin(cc,'nr')

我以前也是这么干的。。。。。呵呵。。。
2023-08-27 16:10
Pgwyg
Rank: 2
等 级:论坛游民
帖 子:28
专家分:20
注 册:2022-6-10
收藏
得分:0 
不知道VFP有自己的函数,领教了,谢谢!
2023-08-27 16:25
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:647
专家分:2502
注 册:2018-3-13
收藏
得分:0 
如果是研究算法实现也就无可厚非,关键你的 DECtoHEX 有瑕疵
图片附件: 游客没有浏览图片的权限,请 登录注册

这家伙很懒,啥也没留下
2023-08-27 16:39
foxfans
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:112
专家分:324
注 册:2021-10-23
收藏
得分:5 


[此贴子已经被作者于2023-8-27 18:20编辑过]

2023-08-27 17:27
Pgwyg
Rank: 2
等 级:论坛游民
帖 子:28
专家分:20
注 册:2022-6-10
收藏
得分:0 
回复 5楼 csyx
这一点我不知如何操作,读入的数据是字符型,例如“41cc0000”,怎样用CToBin()函数取值?CToBin(0h4cc40000,'nr')的结果是正确的,但是“41cc0000”字符串如何转换成数值0h41cc0000?谢谢!
2023-08-27 17:37
foxfans
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:112
专家分:324
注 册:2021-10-23
收藏
得分:0 
CToBin(STRCONV("41cc0000",16),'nr')
2023-08-27 17:46
tigerpub
Rank: 2
等 级:论坛游民
帖 子:14
专家分:20
注 册:2023-4-20
收藏
得分:5 
回复 6楼 foxfans
2023-08-27 17:55
tigerpub
Rank: 2
等 级:论坛游民
帖 子:14
专家分:20
注 册:2023-4-20
收藏
得分:0 
回复 8楼 foxfans
大佬。
2023-08-27 17:56
快速回复:关于浮点数转换的问题,请大侠指教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013835 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved