| 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.
|