技术论坛

 回复:关于ASCII码转浮点数的讨论

返回主题列表
作者 主题
dcount107
侠圣

经验值:2840
发帖数:1737
精华帖:55
楼主    2009-09-14 17:56:17
主题:关于ASCII码转浮点数的讨论
目前正在做一个通讯的测试,对方发给我的是类似B1.234-4.32E的ASCII码,我要将其中的1.234和-4.32提取出来并转换成浮点数,也就是说xxxxx这样5个字节的数据,首位有可能是ASCII码-号,而且小数点位置不固定。

把库里的块看了个遍,没有找到具有类似功能的块,库里的FC39(STRING_R)貌似只支持科学表示法的小数字符串。

自己编写程序,目前的思路是:
1、判断首字节是否为ASCII码的'-',判断正负
2、查找"."所在字节位置
3、计算整数部分值:∑{单字节ASCII转换为整数*10^(n)}
4、计算小数部分值:∑{单字节ASCII转换为整数*10^(n)}
5、相加并乘以乘以正负符号

不知各位有何高见。
非淡泊无以明志,非宁静无以致远
四书五经
侠圣

经验值:3667
发帖数:762
精华帖:58
    2009-09-16 16:15:18
精华帖  主题:回复:关于ASCII码转浮点数的讨论
我用STL写了一个程序,调试通过了,以下为源代码,有简单的注释.
变量说明如下:
LD30---用做指针,做间接寻址,临时变量
Sum_int---整数部分值,临时变量
Sum_Fra---小数部分值,临时变量
Sign---符号值(1,-1),临时变量
N---小数部分的除数
Err---输出错误标志,输出值
Real_val---输出浮点值
OPN DB 1
L P#0.0
T LD 30
//正符号判断
L DBB [LD 30]
L '-'
==I
L -1
T #Sign
JC lop6
L DBB [LD 30]
L '+'
==I
L 1
T #Sign
JC lop6
lop4: SET //错误处理
= #Err
BEU
//赋初值
lop6: L 0
T #Sum_int
T #LoopCount
T #Sum_Fra
L 0.000000e+000
T #Real_Val
lop2: L #LoopCount
INC 1
T #LoopCount
L 4
>I
JC lop3 //超过字符串最大值,循环结束
L P#1.0
L LD 30
+D
T LD 30
L DBB [LD 30]
L '.'
==I
JC lop3 //找到小数点
L DBB [LD 30]
L '0'
JC lop4 //<于‘0’,出错
L DBB [LD 30]
L '9'
>I
JC lop4 //大于‘9’,出错
L DBB [LD 30]
L '0'
-I
L #Sum_int
+I
T #Sum_int
L 10
*I
T #Sum_int
JU lop2
lop3: L #LoopCount
L 4
>I
JC lop9 //没有小数点,转计算最后值
L P#1.0
L LD 30
+D
T LD 30
L #LoopCount
INC 1
T #LoopCount
L 1
T #N
lop7: L DBB [LD 30]
L '0'
-I
L #Sum_Fra
+I
T #Sum_Fra

L 10
*I
T #Sum_Fra
L #N
L 10
*I
T #N
L P#1.0
L LD 30
+D
T LD 30
L #LoopCount
INC 1
T #LoopCount
L 4
<=I
JC lop7
lop9: L #Sum_int
ITD
DTR
L 1.000000e+001
/R //前面计算多乘了10
T LD 12
L #Sum_Fra
ITD
DTR
L 1.000000e+001
/R //前面计算多乘了10

L #N
ITD
DTR
/R //除以N,得到小数
L LD 12
+R //小数+整数
L #Sign
ITD
DTR
*R //乘以符号位
T #Real_Val
dcount107
侠圣

经验值:2840
发帖数:1737
精华帖:55
    2009-09-21 08:27:48
精华帖  主题:回复:关于ASCII码转浮点数的讨论
感谢各位精彩的回答,尤其是Zane版主提供了一个新的思路。
以下是根据我自己的思路写的SCL程序,供大家参考:
FUNCTION FC70 : VOID //ASCII码转浮点数'0.123'->0.123
TITLE = 'ASCII 2 Float Data by dcount'
VERSION: '1.0';
AUTHOR: 'dcount';
NAME: 'ASCII2R';
FAMILY: 'CITICHMA';
VAR_INPUT
// Input Parameters
DBNO:WORD;
StartByte:INT;
END_VAR

VAR_OUTPUT
// Output Parameters
OutReal:REAL;
END_VAR

VAR_TEMP
// Temporary Variables
TempLoop:INT;
TempValue:INT;
TmpSignal:REAL; //符号
PointPos:INT; //小数点位置
TempReal:REAL;
END_VAR

LABEL
OVER;
END_LABEL

BEGIN
//初始化代码段*****************
OutReal:=0.0;
TmpSignal:=1.0;
PointPos:=StartByte+1;
//初始化代码段*****************

//错误检测代码段*****************
FOR TempLoop:=StartByte TO StartByte+4 BY 1 DO
TempValue:=BYTE_TO_INT(WORD_TO_BLOCK_DB(DBNO).DB[TempLoop]);
IF NOT (TempValue=45 OR TempValue=46 OR (TempValue>=48 AND TempValue<=57)) THEN //'-'=45,'.'=46
//如果有任一字符不属于(0~9.-),则退出程序
OutReal:=0.0;
GOTO OVER;
END_IF;
IF TempValue=46 THEN
PointPos:=TempLoop;
END_IF;
END_FOR;
IF PointPos<=StartByte OR PointPos>=StartByte+4 THEN
GOTO OVER;
END_IF;
//错误检测代码段*****************

//符号位检测代码段*****************
IF WORD_TO_BLOCK_DB(DBNO).DB[StartByte]=B#16#2D THEN TmpSignal:=-1.0; END_IF;
//符号位检测代码段*****************

//整数小数分割代码段*****************
IF WORD_TO_BLOCK_DB(DBNO).DB[StartByte]=B#16#2D THEN //如果首位为-号
FOR TempLoop:=StartByte+1 TO PointPos-1 BY 1 DO
TempReal:=INT_TO_REAL(BYTE_TO_INT(WORD_TO_BLOCK_DB(DBNO).DB[TempLoop])-48); //计算整数部分和
OutReal:=OutReal+TempReal*EXPD(PointPos-TempLoop-1);
END_FOR;
FOR TempLoop:=PointPos+1 TO StartByte+4 BY 1 DO
TempReal:=INT_TO_REAL(BYTE_TO_INT(WORD_TO_BLOCK_DB(DBNO).DB[TempLoop])-48); //计算小数部分和
OutReal:=OutReal+TempReal*EXPD(PointPos-TempLoop);
END_FOR;
ELSE
FOR TempLoop:=StartByte TO PointPos-1 BY 1 DO
TempReal:=INT_TO_REAL(BYTE_TO_INT(WORD_TO_BLOCK_DB(DBNO).DB[TempLoop])-48); //计算整数部分和
OutReal:=OutReal+TempReal*EXPD(PointPos-TempLoop-1);
END_FOR;
FOR TempLoop:=PointPos+1 TO StartByte+4 BY 1 DO
TempReal:=INT_TO_REAL(BYTE_TO_INT(WORD_TO_BLOCK_DB(DBNO).DB[TempLoop])-48); //计算小数部分和
OutReal:=OutReal+TempReal*EXPD(PointPos-TempLoop);
END_FOR;
END_IF;
OutReal:=OutReal*TmpSignal;
//整数小数分割代码段*****************

OVER:;
END_FUNCTION
非淡泊无以明志,非宁静无以致远
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。