小弟在RPGIII中遇到一个类型转换的问题,请教各位
欲将一字符型的变量转换成数字型,字符型变量中的小数点位置不确定.
例:变量可能为下列值
0.1200
12.1
15.999
...
请问有什么好的办法吗?
在RPGIII中好像没有类型转换的操作码或函数,是吗?
span1024 回复于:2005-07-14 11:36:28 |
1,保证字符右对齐,我的意思是:假定你的字符串为8位,按你给定的值如下对齐:
bb0.1200 bbbb12.1 bb15.999 2,然后用MOVE操作转换类型就可以了. |
zuozhenglin 回复于:2005-07-14 12:56:16 |
span1024:这样好像不行吧?
1.字符串本身是左对齐的,如果要转换成右对齐,并不是很方便 2.带小数点的字符串本身并不能用MOVE操作给数字型的变量赋值 |
span1024 回复于:2005-07-14 13:50:17 |
没有试过,就想当然的下结论是个很不好的习惯.
再重申一次在RPG/400中,字符转数字上面说的方法绝对是正确的.当然还有其它方法,但上面的方法是最好的,信不信由你,另外把一个字符串从左对齐转为右对齐不是一件很困难的事. |
majorz 回复于:2005-07-14 14:18:11 |
樓上說的是正確地:
如果原123是字符型, move 123 a 4 movel a b(factor2) 6(len) 2(dec) 將轉化為數字類型 result: b= 123.00 |
zuozhenglin 回复于:2005-07-18 09:09:01 |
呜呜.....还是不行啊!
我用传送的方法试过怎么也不行,原因: 1、带小数位的字符串怎么也不能传给数字型的变量,使用时程序非法退出,出错信息“Error RPG0907 caused program AAAR3 to stop. ”; 2、请问字符串从左对齐转化为右对齐有什么好办法?(显示文件中的右对齐除外); 3、楼上举的实例其实是一个特例。 move 123 a 4 //a=“ 123” movel a b(factor2) 6(len) 2(dec) //其实是相当于左传值“012300”,b自然等于“123.00”,但如果a是6位长的字符串又将怎么样呢?其b的结果等于“1.23”,自然这个结果不是我们所希望的。如果a的值等于“1.23”,结果就是非法退出。 |
fxf_china 回复于:2005-07-18 11:41:58 |
以前也没问别人,自己写了段RPG转,期待好的方法 |
rodenmao 回复于:2005-07-18 13:00:31 |
关键问题是字符串中带有“.”,
提供一个思路: 1、将字符串右对齐; 2、用‘.’ SCAN W#CHAR I,找出小数点的位置,J=总长-I; 3、讲小数点左边的字符和右边的放到一个整数变量中W#DEC1; 4、将W#DEC1/J即可。 (用数组实现) |
majorz 回复于:2005-07-18 15:16:28 |
[quote:c592b713e3="majorz"]樓上說的是正確地:
如果原123是字符型, move 123 a 4 movel a b(factor2) 6(len) 2(dec) 將轉化為..........[/quote:c592b713e3] 抱歉,這個方法對你說的數據卻有問題. |
roden 回复于:2005-07-18 15:39:08 |
[quote:8e9338f0a6="rodenmao"]关键问题是字符串中带有“.”,
提供一个思路: 1、将字符串右对齐; 2、用‘.’ SCAN W#CHAR I,找出小数点的位置,J=总长-I; 3、讲小数点左边的字符和右边的放到一个整数变量中W#DEC1; 4、将W#DEC..........[/quote:8e9338f0a6] 我说错了,最后一步要做这样的处理: J=10**J(10的J次方) |
majorz 回复于:2005-07-18 16:34:04 |
用了一個很笨的方法,請大家看看 ,有不合理的地方請高手指正.
A 為你要轉換的數據. 其中E的長度和F6....F0的長度要根據 A 的長度確定. C '.' SCAN A C 3 0 21 C *IN21 IFEQ '0' C C SUB 1 C C C SUBST A:1 E 6 C ' ' SCAN E:C Z 3 0 C SELEC C Z WHEQ 6 C MOVEL E F6 5 C MOVE F6 FX 8 C Z WHEQ 5 C MOVEL E F5 4 C MOVE F5 FX 8 C Z WHEQ 4 C MOVEL E F4 3 C MOVE F4 FX 8 C Z WHEQ 3 C MOVEL E F3 2 C MOVE F3 FX 8 C Z WHEQ 2 C MOVEL E F2 1 C MOVE F2 FX 8 C Z WHEQ 1 C MOVEL E F1 6 C MOVE F1 FX 8 C Z WHEQ 0 C MOVEL E F0 6 C MOVE F0 FX 8 C ENDSL C ADD 2 C C SUBST A:C D 4 C ' ':'0' XLATE D D C FX CAT D Y 12 C MOVE Y X 124 C ENDIF C SETON LR X 為要轉換後的值. 如果要用rpg4的話將很好實現啊.另外,為伸麼lz的數據有小數點的字符型,偶從沒遇到過. |
fxf_china 回复于:2005-07-18 17:37:06 |
凑热闹,^_^,没有用SCAN,惭愧
1,定义E表 E STN 50 1 E STN1 50 1 E STN2 50 1 2, C*================================= C* S#STN - STRING TO NUMBER C*================================= C* 输入: STN C* 输出: W#STNZ C S#STN BEGSR C CLEARSTN1 C CLEARSTN2 C MOVEL'0' W#STNF 1 C Z-ADD50 K 40 C Z-ADD50 L 40 C Z-ADD0 M 40 C DO 50 I 40 C* 后面开始查找 C 51 SUB I J 40 C* 小数部分 C STN,J IFNE *BLANK C STN,J ANDNE'.' C W#STNF ANDEQ'0' C ADD 1 M C MOVE STN,J STN1,K C SUB 1 K C ENDIF C* 小数 C STN,J IFEQ '.' C MOVEL'1' W#STNF C ENDIF C* 整数部分 C STN,J IFNE *BLANK C STN,J ANDNE'.' C W#STNF ANDEQ'1' C MOVE STN,J STN2,L C SUB 1 L C ENDIF C ENDDO C CLEARW#STN1 C CLEARW#STN2 C CLEARW#STND C CLEARW#STNE C Z-ADD1 W#STNV C W#STNF IFEQ '0' C* 没有小数点的情况 C MOVEASTN1 W#STN1 50 C MOVE W#STN1 W#STND 100 C Z-ADDW#STND W#STNZ 199 C ELSE C* 有小数点的情况 C MOVEASTN1 W#STN1 50 C MOVEASTN2 W#STN2 50 C MOVE W#STN1 W#STND 100 C DO M I C W#STNV MULT 10 W#STNV 100 C ENDDO C W#STND DIV W#STNV W#STNZ C MOVE W#STN2 W#STNE 90 C ADD W#STNE W#STNZ 199 C ENDIF C* C E#STN ENDSR |
zuozhenglin 回复于:2005-07-19 23:03:46 |
感谢各位的热心帮助,小弟仔细阅读了各位的回复,有如下看法:
1、majorz 的方法好像有点问题,如果没有记错的话SCANR操作码找到了因子1说明的字符时是将指示器置为ON,其它有C ' ' SCAN E:C Z 3 0的位置好像也有点问题。 2、fxf_china的方法应该可以。但因为现在在家无法测试,明天到公司测试一下。 3、根据各位的思路,小弟也写了一段代码。思路是:将整数部分左传给一个等长的数字变量,必然放大:10的(总字符串长-整数部分的长)次方倍,除以它得到整数部分。小数部分左传给一个等长的数字变量,必然放大:10的(数字长)次方倍,除以它得到小数部分。两者相加得想要的值。代码如下:(测试通过) C* 输入: A C* 输出: #A C '.' SCAN A WL 20 30 小数点位置 C ' ' CHEKRA WN 20 31 空格位置 C N31 Z-ADD10 WN C* 整数部分数字化 C*WA: 整数部分; WB :小数部分; WX: 整数部分放大倍数; WY: 小数部分放大倍 C* 小数点存在时 C *IN,30 IFEQ '1' C WL SUB 1 W#L 20 C W#L SUBSTA:1 W#A 10 P C Z-ADD1 WX 100 C 10 SUB W#L WM 30 C 1 DO WM C MULT 10 WX C ENDDO C MOVELW#A WA 100 C DIV WX WA C* C WL ADD 1 WO 30 C SUBSTA:WO W#B 10 P C 100 MULT 100000000 WY 110 C MOVELW#B WB 199 C DIV WY WB C*小数点不存在时 C ELSE C MOVELA W#A C Z-ADD1 WX 100 C 10 SUB WN WM C 1 DO WM C MULT 10 WX C ENDDO C MOVELW#A WA C DIV WX WA C Z-ADD0 WB C ENDIF C* C WA ADD WB #A 199 |
majorz 回复于:2005-07-20 08:41:20 |
zuozhenglin
確定的對你說SCAN操作码找到了因子1说明的字符时是将指示器置为off, 另外 ' ' SCAN E:C Z 3 0掃描位置也沒有問題. |
zuozhenglin 回复于:2005-07-20 11:32:51 |
majorz:对SCAN操作码我刚查资料证实你的说法的确有误. |
majorz 回复于:2005-07-20 13:25:49 |
謝謝zuozhenglin兄弟, 幫俺糾正了一個錯誤,以前用scan都沒用指示器就發現錯誤. :oops: :oops: |
Eagle_wolf 回复于:2005-07-20 17:49:11 |
rpgIII 有没有指针? 有的话可以试一下指针 |
zuozhenglin 回复于:2005-07-21 08:41:16 |
据我了解RPGIII没有指针 |
大肥肥 回复于:2005-07-29 11:56:10 |
SQL有一个函数可以解决DECIMAL,可以想办法调用一下。
写一个sqlcbl程序很可以,传入一个参数,就是你的字符串: 做一个文件LIB/FILE1,里面有一个数字型FIELD来接受输出的数字型变量。然后用一个循环来判断小数点的位置,字符串长度为L, 小数点位置N. 之后调用如下: EXEC SQL INCLUDE SQLCA END-EXEC. LINKAGE SECTION. 01 LINK-STRING PIC X(20). ************************************** * PROCEDURE DIVISION * ************************************** PROCEDURE DIVISION USING LINK-STRING. MAIN SECTION. MAIN-PROCESS. PERFORM 100-PROCESS THRU 100-PROCESS-EXIT. 100-PROCESS. EXEC SQL UPDATE LIB/FILE1 SET FIELD = :DECIMAL (LINK-STRING,L,N) END-EXEC. 100-PROCESS-EXIT. EXIT. |
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/