Recursion is a mechanism whereby repetition can be achieved using (at its simplest) a procedure or function that continuous to call itself until some base case is reached. We say that a recursive algorithm winds up until the base case is reached and then unwinds. Note that during the unwinding process further program statements may be called. Thus a recursive algorithm requires:
Develop and implement some Ada software which, when given a natural decimal number, will convert this integer into a binary number. For example, given the number 41 we would expect the system to output:
00000000 00000000 00000000 00101001
The standard mechanism, for converting from decimal to binary is to repeatedly divide the decimal number by 2 and, at each division, output the remainder (0 or 1). An example is given to the right where the binary number 101001 is derived from the decimal number 41.
A top down analysis of the problem is given below.
We will implement this using the following procedures:
NAME | DESCRIPTION | TYPE | RANGE |
---|---|---|---|
NATURAL_NUMBER | Global input variable | NATURAL | Default |
NAME | DESCRIPTION | TYPE | RANGE |
---|---|---|---|
DECL_NUM | Formal parameter | NATURAL | Default |
DIGIT_COUNTER | Formal parameter | NATURAL | Default |
NAME | DESCRIPTION | TYPE | RANGE |
---|---|---|---|
DIG_COUNT | Formal parameter | NATURAL | Default |
END_VALUE | Local variable | INTEGER | Default |
An appropriate Nassi Shneiderman design is given below.
Here we have used a recursive algorithm to ensure that the binary digits are output in the correct order. If we used a simple while loop the reverse result would be produced. A flow chart indicating the overall flow of control through the proposed software is given below.
The encoding of the above design is as follows:
-- DECIMAL 2 BINARY -- 17 September 1997 -- Frans Coenen -- Dept Computer Science, University of Liverpool with TEXT_IO; use TEXT_IO; procedure DECIMAL_2_BINARY is package INTEGER_INOUT is new INTEGER_IO(INTEGER); use INTEGER_INOUT; DECIMAL_NUMBER: NATURAL; --------------------------------------------------------------------------- -- CONVERT procedure CONVERT(DEC_NUM, DIGIT_COUNTER: INTEGER) is ----------------------------------------------------------------------- -- PAD WITH ZEROES procedure PAD_WITH_ZEROES(DIG_COUNT: NATURAL) is END_VALUE: INTEGER; begin END_VALUE := 32-DIG_COUNT; for LOOP_PARAMETER in 1..END_VALUE loop PUT("0"); if (LOOP_PARAMETER rem 8 = 0) then PUT(" "); end if; end loop; end PAD_WITH_ZEROES; ----------------------------------------------------------------------- begin -- Output digits and spaces between bytes when appropriate if DEC_NUM /= 0 then; CONVERT(DEC_NUM/2, DIGIT_COUNTER+1); PUT(DEC_NUM rem 2, WIDTH=>1); if (LOOP_PARAMETER rem 8 = 0) then PUT(" "); end if; else PAD_WITH_ZEROES(DIGIT_COUNTER); end if; end CONVERT; --------------------------------------------------------------------------- -- TOP LEVEL begin PUT("Input a natural integer: "); GET(DECIMAL_NUMBER); NEW_LINE; PUT(DECIMAL NUMBER) PUT(" = "); CONVERT(DECIMAL_NUMBER,0); NEW_LINE; end DECIMAL_2_BINARY;
BVA, Limit and Arithmetic testing: Use BVA testing to analyse nature of inputs. Limit testing to test operation of the software at the limits, and arithmetic te sting to test the arithmetic expressions. A suggested set of test cases is given in the following Table.
TEST CASE | EXPECTED RESULT |
---|---|
DECIMAL_NUMBER | OUTPUT |
-1 | CONSTRAINT_ERROR |
0 | 00000000 00000000 00000000 00000000 |
1 | 00000000 00000000 00000000 00000001 |
1073741823 | 00111111 11111111 11111111 11111111 |
2147483646 | 01111111 11111111 11111111 11111110 |
2147483647 | 01111111 11111111 11111111 11111111 |
2147483648 | DATA_ERROR |
Path testing: We should test all paths identified in the flow charts given in Tables 3 and 4. This is already achieved by the above test cases.
Loop testing: The loop is a variable count loop therefore we should test the the loop with 1, 2 and some other number of passes through the loop. Again this will be achieved by the test cases given above.
This should also be done.
Example Problem Decimal to Binary Conversion Report.
Design and Produce some software, written in Ada, that outputs the Nth term in a Fibonacci Sequence:
0, 1, 1, 2, 3, 5, 8, 13 ....
where the first two, terms are 0 and 1 , and each term thereafter is the sum of the two proceeding terms. Thus:
Fib(N) = Fib(N-1) + fib(N-2)
where N is greater than 2. Assume that the N is a positive integer in the range 1..30 inclusive.
A top down analysis of the problem is given below.
The above can be implemented using the following procedures/functions
NAME | DESCRIPTION | TYPE | RANGE |
---|---|---|---|
TERM_NUM | Formal_parameter | POSITIVE | Default |
NAME | DESCRIPTION | TYPE | RANGE |
---|---|---|---|
TERM_NUM | Formal_parameter | POSITIVE | Default |
Nassi-Shneiderman designs for the above are given below.
The encoding of the above design is as follows:
-- FIBONACCI -- 17 September 1997 -- Frans Coenen -- Dept Computer Science, University of Liverpool with TEXT_IO; use TEXT_IO; procedure FIBONACCI is package INTEGER_INOUT is new INTEGER_IO(INTEGER); use INTEGER_INOUT; TERM_NUMBER: POSITIVE range 1..30; ----------------------------------------------------------------------- -- FIBONACCI function FIBONACCI_TERM(TERM_NUM: POSITIVE) return INTEGER is begin case TERM_NUM is when 1 => return 0; when 2 => return 1; when others => return FIBONACCI_TERM(TERM_NUM-1) + FIBONACCI_TERM(TERM_NUM-2); end case; end FIBONACCI_TERM; ----------------------------------------------------------------------- -- TOP LEVEL PROCEDURE BEGIN -- Input required term number PUT_LINE("Input term number (positive integer 1..30): "); GET(TERM_NUMBER); -- Calculate and output term PUT("Fib("); PUT(TERM_NUMBER, WIDTH=>1); PUT(") = "); PUT(FIBONACCI_TERM(TERM_NUMBER)); NEW_LINE; end FIBONACCI;
TEST CASE | EXPECTED RESULT |
---|---|
TERM_NUMBER | OUTPUT |
0 | CONSTRAINT_ERROR |
1 | 0 |
2 | 1 |
29 | ? |
30 | ? |
31 | CONSTRAINT_ERROR |
BVA, Limit and Arithmetic Testing. Test range and limits for TERM_NUMBER input variable and arithmetic expressions using test cases of the form presented in the table right.
Path testing: Test all paths through FIBONACCI_TERM function. This is adequately achieved by the set of test cases presented above right.
Note: no loop testing will be required although we should carry out some data validation tests.
Example Problem Fibonacci Report.
Created and maintained by Frans Coenen. Last updated 11 October 1999