%XFOOT with %LEN PDF Print E-mail
Written by Robert Cozzi   
Tuesday, 19 September 2006

When attempting to calculate the number of bytes of storage an array occupies, the %SIZE built-in function may be used. Include the second parameter *ALL to get the number of bytes of memory the entire array occupies.

But what about determining the length of the elements in an array? For example, an array of 10 elements, each being 9-position packed with zero decimals, is specified as follows:

     D qty             S              9P 0 Dim(10)

Apply %size to the QTY array to calculate the number of bytes, as follows:

bytes = %size(qty);
allBytes = %size(qty : *ALL);

This yields 5 and 50, respectively. A 9-digit packed field occupies five bytes of memory; therefore, each element has a size of 5 bytes, whereas all 10 elements have a combined size of 50 bytes.

When the declared length of an array element is different from its size (bytes occupied), then the %LEN built-in function can be used to retrieve the length of the element. For example:

len = %len(qty);

This yields a length of 9. Unlike %SIZE, the %LEN built-in function does not support an *ALL parameter. Therefore, another approach must be taken. This is where %XFOOT comes in.

An anomaly of %XFOOT is that if it encloses a %LEN that is further enclosing an array, %XFOOT will add up the lengths of the elements in the array.

Here’s how to use %XFOOT to calculate total length of all array elements:

 

     D qty             S              9P 0 Dim(10)
     D totDigits       S             10I 0
      /free
         totDigits = %XFoot(%len(qty));
             // totDigits is equal to 90
      /end-free

The %XFOOT built-in function magically adds up the lengths of each of the array elements for the array specified within the %LEN built-in function.

For arrays with character elements, the length and size care identical, unless the VARYING keyword is used. In this case, the technique can be used to calculate the current length of each of the variable-length elements in the array.

Here’s how to use %XFOOT with VARYING array elements:

 

     D NAMES           S             20A   Dim(20) VARYING
     D totLen          S             10I 0
      /free
         names(1) = 'Bob';
         names(2) = 'Bobby';
         names(3) = 'Robert';
      
         totLen = %XFoot(%len(names));
             // Only elems 1 to 3 have data
             // Therefore elems 4 to 20 are empty
             // totLen is equal to 14
      /end-free

Another option is to use the %SUBARR built-in function (added in OS/400 V5R3), which allows an array to be subscripted. This allows you to add up the lengths of just the desired elements in the array.

Here’s how to use %XFOOT with %SUBARR to sum up lengths of elements 1 to 3:

 

     D NAMES           S             20A   Dim(20) VARYING
     D totLen          S             10I 0
      /free
         names(1) = 'Bob';
         names(2) = 'Bobby';
         names(3) = 'Robert';
      
         totLen = %XFoot(%len(%subarr(names:1:3)));
             // Only elems 1 to 3 are used
             // totLen is equal to 14
      /end-free

 

 

 

 

Bob Cozzi is a programmer/consultant, writer/author, and software developer of the RPG xTools, a popular add-on subprocedure library for RPG IV. His book The Modern RPG Language has been the most widely used RPG programming book for nearly two decades. He, along with others, speaks at and runs the highly-popular RPG World conference for RPG programmers.

 


Last Updated ( Tuesday, 27 May 2008 )
 
Discuss (9 posts)
prswain
%XFOOT with %LEN
Sep 22 2006 12:28:00
Array in array out for most all bifs. Makes sense.<br><br>
So for fixed length arrays we can do:<br>
totLen = %xfoot(%len(%trim(names)))<br><br>
or for decimal arrays:<br>
totLen = %xfoot(%len(%char(amounts)))<br>
totLen = %xfoot(%len(%trim(%editc(amounts:'Z'))))<br>
evalr array = %char(amounts)<br><br>
I like it.
#120716

H.Boldt
%XFOOT with %LEN
Sep 22 2006 09:44:00
You're right. I realized my mistake on the drive home last night. Yes, "%len(ary<b>(1)</b>)*%elem(ary)" is what I should have recommended. <p>It may be a normal feature of the language, but the inconsistency still looks goofy (IMO). <p>(Although I can see some potential use for "%xfoot(%len(ary))" for char varying arrays, I still don't see much point for anything else.) <p>Cheers! Hans
#120715
Barbara Morris
%XFOOT with %LEN
Sep 21 2006 22:26:00
Nope. %len(ary) gets a diagnostic about a missing index. <p>But %len(ary(1)) * %elem(ary) would work for anything with fixed-length, and indeed be more efficient than %xfoot. <p>For varying fields, %xfoot(%len(ary)) is exactly what's needed. <p>It's not really an anomaly. It's a normal feature of RPG that %bif(array) returns an array (except for a couple of builtin functions like %SIZE and sometimes %ADDR). <p>%subst(someArray : 2 : 5) returns an array of substrings, which you could assign to another array <p> eval someOtherArray = %subst(someArray : 2 : 5)
#120714

H.Boldt
%XFOOT with %LEN
Sep 21 2006 17:40:00
Paul wrote: "<em>I believe the expression %len(ary)*%elem(ary) would just return a numeric array of lengths with each element multiplied by the number of elements in the array.</em>" <p>Your belief is incorrect. <p>For numeric arrays, the expression "%len(ary)*%elem(ary)" multiplies a scalar constant by a scalar constant. It's been too long for me to remember the details, but the compiler might even do the computation at compile-time. (With optimization, the back-end should figure that out easily anyways.) <p>Cheers! Hans
#120713
prswain
%XFOOT with %LEN
Sep 21 2006 16:37:00
What I find interesting is the returned value(s) of the %len BIF. <BR>
Or any expression containing arrays. <BR>
I believe the expression %len(ary)*%elem(ary) would just return a numeric array of lengths with each element multiplied by the number of elements in the array. <BR>
%xfoot is just doing what it is designed to do; summarize numeric arrays. <BR>
The magic is %len.
#120712
D.Eckersley
%XFOOT with %LEN
Sep 20 2006 14:51:00
That "anomaly" is very obscure, and not everyone will understand the code. <p>I have to go with Hans on this one (though I think he meant %elem, not %dim). It is much clearer.
#120711
mscottx
%XFOOT with %LEN
Sep 20 2006 12:49:00
Bob, <p>That technique is awesome. Good finding, I am sure I will find a use for it someday. <p>Thanks, <BR>
Michael P.
#120710

H.Boldt
%XFOOT with %LEN
Sep 20 2006 11:28:00
First, can you specify a common situation where the sum of the number of digits in the array might be useful? <p>Second, why not code "%len(qty)*%dim(qty)"? That would not only be clearer, but should also be faster. <p>Cheers! Hans
#120709
MC Press Web Site Staff
%XFOOT with %LEN
Sep 22 2006 12:28:00
This is a discussion about <B>%XFOOT with %LEN</b>.<p align='center'><a href=http://www.mcpressonline.com/mc?1@232.1KNKfHX1eQT.17@.6b3a3974>Click here for the article</a>.</p>
#120708


Discuss...
User Rating: / 1
PoorBest 
Related Articles
< Prev   Next >

   MC-STORE.COM