On 09-Dec-2013 16:20 -0800, Scott Klement wrote:
On 12/9/2013 12:44 PM, Dave Shaw wrote:
So would this be preferable?
num4 = %dec(%subst(%char(num6):1:4):4:0);
This code is wrong. %char() will remove leading zeros, and trim the
resulting blanks. So if the input was '000111' the MOVEL example
results in '0001', but your %CHAR() technique would result in '111 '
If you want to use %dec() and %subst() you'll need to also use %EDITC
to preserve the leading zeros.
num4 = %dec(%subst(%editc(num6:'X'):1:4):4:0);
Likely not an issue for the scenario in the OP, per a later
clarification that the data "will never involve calculations - IDs
stored as zoned data types", but FWiW...
Even that revised expression may be wrong to properly mimic a MOVEL
between those two numeric variables; again, depending on the values.
That expression loses the sign, but MOVEL maintains the sign from the
source operand. According to the doc: When "Factor 2 is longer than the
result field:" then "If factor 2 and the result field are numeric, the
sign from the rightmost position of factor 2 is moved into the rightmost
position of the result field."
Oddly, the visual example in the docs contradicts the above doc quote:
<
http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/rzasd/sc092508972.htm#zzmovel>
IBM i 7.1 Information Center -> Programming -> Programming languages ->
RPG -> ILE RPG Language Reference -> Operations, Expressions, and
Functions -> Chapter 22. Operation Codes
_i MOVEL (Move Left) i_
"...
The MOVEL operation transfers characters from factor 2 to the result
field. Moving begins with the leftmost character in factor 2. ...
When data is moved to a numeric field, the sign (+ or -) of the result
field is retained *except when factor 2 is as long as or longer* than
the result field. In this case, *the sign of factor 2 is used* as the
sign of the result field.
...
If the resulting data is too long to fit the result field, the data will
be truncated. ...
The MOVEL operation is summarized in _Figure 347_.
A summary of the rules for MOVEL operation for four conditions based on
field lengths:
1. Factor 2 is the same length as the result field:
...
2. Factor 2 is longer than the result field:
a. If factor 2 and the result field are numeric, the sign from the
rightmost position of factor 2 is moved into the rightmost position of
the result field.
...
..."
<
http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/rzasd/sc092508972.htm#mvelopr>
_Figure 347. MOVEL Operation_
"...
_Factor 2 Longer Than Result Field_
<ed: shows, effectively:>
a. 9-digit Numeric to 5-digit Numeric:
Value of Factor 2: 000258425- x'F0F0F0F2F5F8F4F2D5'
Result Before MOVEL: 56784+ x'F5F6F7F8F4'
Result After MOVEL: 00025 x'F0F0F0F2F5'
..."
According to the text, in contradiction with what is shown in the
figure 347, and contradicting the effects seen in actual testing, the
above figure should have shown instead:
a. 9-digit Numeric to 5-digit Numeric:
Value of Factor 2: 000258425- x'F0F0F0F2F5F8F4F2D5'
Result Before MOVEL: 56784+ x'F5F6F7F8F4'
Result After MOVEL: 00025- x'F0F0F0F2D5'
Personally, my vote would be %div(num6:100) which is every bit as
valid and self-documenting as MOVEL.
That expression is quite accurate in mimicking the original MOVEL for
the given scenario [Factor 2 Longer than Result Field, numeric to
numeric], as far as I know; including maintaining the sign.
And possibly worth knowing... Each of the MOVEL and the latter two
revised expressions "num4 =" will detect decimal data errors whenever
either the digits portion or sign are invalid while ignoring any invalid
zone portions, and will implicitly /correct/ the zone portion and force
the sign nibble to the preferred value [0xF for positive or 0xD for
negative] for the result.
As an Amazon Associate we earn from qualifying purchases.