| 作者 | 主题 |
|---|---|
|
dcount107 侠圣 经验值:2840 发帖数:1737 精华帖:55 |
楼主
主题:关于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 |
楼
主题:回复:关于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 |
楼
主题:回复:关于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
非淡泊无以明志,非宁静无以致远
|