REPETITION - `REVERSE' FOR LOOPS


1. OVERVIEW

It is sometimes desirable to process a fixed count loop backwards, i.e. in reverse. In some imperative languages this can be achieved simply by adjusting the nature of the incrementation (decrementations) and the nature of the start value. However in Ada, where we can only increment by +1 this option is not available. Instead we can include the reserved word reverse in our loop definition. For example the statement:

for NUMBER in reverse 1..5 loop
        PUT(NUMBER);
end loop;

would produce the output:

5       4       3       2       1

2. EXAMPLE PROBLEM FACTORIAL


2.1 Requirements

Design and implement an Ada program that returns the value of N! (N Factorial) given a specific value for N. Note:

n! = n x (n-1) x (n-2) ... 3 x 2 x 1

For example:

10!= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 3628800

Note also that N must be a positive integer and assume that the maximum permissible value for N is 12.


2.2 Design

A top down analysis of the problem is given below.

TOP DOWN ANALYSIS

The operations identified above are trivial enough to be implemented as a single procedure incorporating a single fixed count loop.

  1. FACTORIAL (top level procedure). Input number of terms and calculate product.
    NAMEDESCRIPTIONTYPERANGE
    NUMBER_OF_TERMSGlobal input variablePOSITIVE1..12
    PRODUCTGlobal variablePOSITIVEDefault
NASSI_SHNEIDERMAN CHART

So as to adhere to the generally accepted mathematical definition of factorial(N) we will process the loop in reverse. An appropriate Nassi-Shneiderman chart is given to the right.


2.3. Implementation

The encoding of the above design is as follows:

-- FACTORIAL
-- 15 September 1997
-- Frans Coenen
-- Dept Computer Science, University of Liverpool

with TEXT_IO;
use TEXT_IO;

procedure FACTORIAL is
    package INTEGER_INOUT is new INTEGER_IO(INTEGER);
    use INTEGER_INOUT;
    NUMBER_OF_TERMS : POSITIVE range 1..12;
    PRODUCT         : POSITIVE;
begin
-- Input N_VALUE
    PUT_LINE("Input number of terms (integer 1..12): ");
    GET(NUMBER_OF_TERMS);
    PRODUCT := NUMBER_OF_TERMS;
-- For loop
    for COUNTER in reverse 1..NUMBER_OF_TERMS-1  loop
        PRODUCT := PRODUCT*COUNTER;
    end loop;
-- Output result
    PUT(NUMBER_OF_TERMS);
    PUT("! = ");
    PUT(PRODUCT);
    NEW_LINE;
end FACTORIAL;

2.4. Testing

2.4.1 Black box testing

BVA, Limit and Arithmetic Testing. A suitable set of test cases is given in the table below.

TEST CASEEXPECTED RESULT
NUMBER_OF_TERMSOUTPUT
0CONSTRAINT_ERROR
11
22
6720
1139916800
12479001600
13CONSTRAINT_ERROR

2.4.2 White box testing

Loop testing. Test repetitions in fixed count loop using set of test cases of the form given below. Note that, except for the third test case ("two passes through loop") all these have been run as either BVA, limit or arithmetic test cases (see above).

TEST CASEEXPECTED RESULT
NUMBER_OF_TERMSOUTPUT
1 (no passes through loop)1
2 (one pass) 2
3 (two passes) 6
6 720
11 (end value -1 passes) 39916800
12 (end value passes) 479001600


Example Problem Factorial Report.


4. EFFICIENCY

A well engineered piece of software should make efficient use of critical resources, particularly:

  1. Processing power
  2. Primary memory storage

However, efficiency concerns should not generally override the need for clarity, readability and correctness.

Code efficiency

Code efficiency is generally measured in terms of the number of machine statements that need to be processed. Note that:

  1. A program statement in a high level language may require many machine code statements to implement it.
  2. Different high-level statements will usually have different numbers of machine code statements associated with them.
  3. However, generally speaking the number of high level language statements making up an algorithm is directly proportional to processing efficiency.
  4. The number of statements required to process an algorithm is not necessarily the same as the number of lines of code required to define an algorithm - particularly when using loops.

Memory Efficiency

For most computers memory restrictions are a thing of the past. This is not the case for embedded systems.




Created and maintained by Frans Coenen. Last updated 11 October 1999