不是考虑代码可读性,性能和操作系统版本,
MOVE
opcode和诸如 ATOI
之类的c api之间有什么区别?MOVE
在内部如何工作?
示例:
MOVE ALPHAFLD NUMRCFLD
EVAL NUMRCFLD = ATOI(ALPHAFLD)
在Old O.S.中(< v3r7)我应该什么时候使用MOVE
,什么时候应该使用C API?
atoi()和atof()已"始终"可用。但是RPG程序员已经能够使用%int/%inth或%dec/%dec/%dech将字符串转换为数字自V5R2,左右。%dech和%inth founding。
。有时移动以奇异的方式处理数字。例如,假设您有一个具有5位数字和1个小数位置的变量,当前值为9876.5。现在,您将值" 123"移至该变量。尝试此代码以查看可变" num"中哪些奇异结果。提示:不是123。
D num s 5p 1 inz(9876.5)
D msg s 20
C move '123' num
C eval msg = %char(num)
C msg dsply
C return
这个问题可能是偏离主题的,因为它可能是基于意见的...
但是我给你我的答案。
首先,atoi()
与MOVE
不同。您还需要atol()
和atof()
来处理所有情况MOVE
可以。鉴于小数的数量和/400处理,atof()
特别重要。但是atof()
并不是一个不错的选择,因为浮点与固定十进制的不精确。
,但MOVE
也不是那么好。它不能例如处理负数。
如果您真的卡在OS/400的较旧版本上。我建议IBM RPG IV编译器开发人员芭芭拉·莫里斯(Barbara Morris
H NOMAIN
* Copy prototype for procedure getNum
D/COPY GETNUM_PR
*-------------------------------------------------------
* getNum - see GETNUM_PR for details
*-------------------------------------------------------
p getNum b export
D getNum pi 30p 9
D string 100a const varying
D decCommaParm 2a const options(*nopass)
D curSymParm 1a const options(*nopass)
* defaults for optional parameters
D decComma s 2a inz('.,')
D cursym s 1a inz(' ')
D result s 30s 9 inz(0)
D sign s 1a inz('+')
D i s 10i 0
D len s 10i 0
D c s 1a
* override defaults if optional parameters were passed
C if %parms > 1
C eval decComma = decCommaParm
C endif
C if %parms > 2
C eval cursym = cursymParm
C endif
* call getNumAny to do the work
C callp getNumAny (string
C : %addr(result)
C : %len(result)
C : %decpos(result)
C : decComma
C : curSym)
C return result
p getNum e
*-------------------------------------------------------
* getNumAny
*-------------------------------------------------------
p getNumAny b export
D getNumAny pi
D string 100a const varying
D result * const
D digits 10i 0 const
D decimals 10i 0 const
D decComma 2a const options(*nopass)
D currency 1a const options(*nopass)
* defaults for optional parameters
D decPoint s 1a inz('.')
D comma s 1a inz(',')
D cursym s 1a inz(' ')
* structure for building result
D resChars s 30a based(result)
* variables for gathering digit information
* pNumPart points to the area currently being gathered
* (the integer part or the decimal part)
D pNumPart s *
D numPart s 30a varying based(pNumPart)
D intPart s 30a varying inz('')
D decPart s 30a varying inz('')
* other variables
D intStart s 10i 0
D decStart s 10i 0
D signByte s 1a based(pSignByte)
D sign s 1a inz('+')
D i s 10i 0
D len s 10i 0
D c s 1a
* override defaults if optional parameters were passed
C if %parms > 4
C eval decPoint = %subst(decComma : 1 : 1)
C eval comma = %subst(decComma : 2 :1)
C endif
C if %parms > 5
C eval cursym = currency
C endif
* initialization
C eval len = %len(string)
* begin reading the integer part
C eval pNumPart = %addr(intPart)
* loop through characters
C do len i
C eval c = %subst(string : i : 1)
C select
* ignore blanks, digit separator, currency symbol
C when c = comma or c = *blank or c = cursym
C iter
* decimal point: switch to reading the decimal part
C when c = decPoint
C eval pNumPart = %addr(decPart)
C iter
* sign: remember the most recent sign
C when c = '+' or c = '-'
C eval sign = c
C iter
* more signs: cr, CR, () are all negative signs
C when c = 'C' or c = 'R' or
C c = 'c' or c = 'r' or
C c = '(' or c = ')'
C eval sign = '-'
C iter
* a digit: add it to the current build area
C other
C eval numPart = numPart + c
C endsl
C enddo
* make sure that there is no overflow
C if %len(decPart) > decimals
C or %len(decPart) + %len(intPart) > digits
* Force an overflow exception
C z-add *hival overflowSrc 5 0
C z-add 0 overflowTgt 4 0
C eval overflowTgt = overflowSrc
C endif
* initialize the result to all zeros
C eval %subst(resChars : 1 : digits) = *zeros
* copy the digit strings into the correct positions in the
* zoned variable, using the character overlay
C eval decStart = digits - decimals + 1
C eval intStart = decStart - %len(intPart)
C eval %subst(resChars
C : intStart
C : %len(intPart))
C = intPart
C eval %subst(resChars
C : decStart
C : %len(decPart))
C = decPart
* if the sign is negative, make the result negative
C if sign = '-'
C eval pSignByte = %addr(resChars) + digits - 1
* Change the sign zone from x'f' to x'd' (b'1111' to b'1101')
* using a mask of x'2' (b'0010')
C bitoff X'20' signByte
C endif
p getNumAny e
-----------------------------------------------------------
* Prototype file
D getNum pr 30p 9
D string 100a const varying
D decComma 2a const options(*nopass)
D currency 1a const options(*nopass)
D getNumAny pr
D string 100a const varying
D result * const
D digits 10i 0 const
D decimals 10i 0 const
D decComma 2a const options(*nopass)
D currency 1a const options(*nopass)
*---------------------------------------------------------
* getNum - procedure to read a number from a string
* and return a 30p 9 value
* Parameters:
* I: string - character value of number
* I:(opt) decComma - decimal point and digit separator
* I:(opt) currency - currency symbol for monetary amounts
* Returns: packed(30,9)
*
* Parameter details:
* string: the string may have
* - blanks anywhere
* - sign anywhere
* accepted signs are: + - cr CR ()
* (see examples below)
* - digit separators anywhere
* - currency symbol anywhere
* decComma: if not passed, this defaults to
* decimal point = '.'
* digit separator = ','
* currency: if not passed, defaults to ' '
*
* Examples of input and output (x means parm not passed):
*
* string | dec | sep | cursym | result
* ---------------+-----+-----+--------+------------
* 123 | x | x | x | 123
* +123 | x | x | x | 123
* 123+ | x | x | x | 123
* -123 | x | x | x | -123
* 123- | x | x | x | -123
* (123) | x | x | x | -123
* 12,3 | , | . | x | 12.3
* 12.3 | x | x | x | 12.3
* 1,234,567.3 | x | x | x | 1234567.3
* $1,234,567.3 | . | , | $ | 1234567.3
* $1.234.567,3 | , | . | $ | 1234567.3
* 123.45CR | x | x | x | -123.45
*
* Author: Barbara Morris, IBM Toronto Lab
* Date: March, 2000
芭芭拉(Barbara)还参加了相关讨论,其中上述代码已在comp.sys.ibm.as400.misc新闻组