5 Loops

The previous section showed how the IF statement could be used to cause the same statements to be executed several times. Recall the program:

   10 I=0
   20 PRINT"!"; I=I+1 
   30 IF I<256 GOTO 20
   40 END

which prints out 256 exclamation marks (half a screen full). This iterative loop is such a frequently-used operation in BASIC that all BASICs provide a special pair of statements for this purpose, and ATOM BASIC provides a second type of loop for greater flexibility.

5.1 FOR...NEXT Loops

The FOR statement, together with the NEXT statement, causes a set of statements to be executed for a range of values of a specified variable. To illustrate, the above example can be rewritten using a FOR...NEXT loop as follows:

   10 FOR I=1 TO 256 
   20   PRINT "!" 
   30 NEXT I
   40 END

The FOR statement specifies that the statements up to the matching NEXT statement should be executed for each value of I from 1 to 256 (inclusive). In this example there is one statement between the FOR and NEXT statements, namely:

   PRINT "!"

This statement has been indented in the program to make the loop structure clearer; in fact the spaces are ignored by BASIC.

The NEXT statement specifies the variable that was specified in the corresponding FOR statement. This variable, I in the above example, is called the 'control variable' of the loop; it can be any of the variables A to Z.

The value of the control variable can be used inside the loop, if required. To illustrate, the following program prints out all multiples of 12 up to 12*12:

   10 FOR M=1 TO 12
   20   PRINT M*12 
   30 NEXT M
   40 END

The range of values specified in the FOR statement can be anything you wish, even arbitrary expressions. Remember, though, that the loop is always executed at least once, so the program:

   10 FOR N=1 TO 0
   20   PRINT N 
   30 NEXT N
   40 END

will print '1' before stopping.

5.1.1 STEP Size

It is also possible to specify a STEP size in the FOR statement; the STEP size will be added to the control variable each time round the loop, until the control variable exceeds the value specified after TO. If the STEP size is omitted it is assumed to be 1. This provides us with an alternative way of printing the multiples of 12:

   10 FOR M=12 TO 12*12 STEP 12
   20   PRINT M
   30 NEXT M
   40 END

5.1.2 Graph Plotting Using FOR...NEXT

The FOR...NEXT loop is extremely useful when plotting graphs using the ATOM's graphics facilities. Try rewriting the Cubic Curve program of Section 4.10.1 using a FOR...NEXT loop.

The following curve-stitching program is quite fun, especially in the higher graphics modes. It simulates the curves produced by stitching with threads stretched between two lines of holes in a square of cardboard. The curve produced as the envelope of all the threads is a parabola:

    1 REM Curve Stitching in a Square
   10 V=46
   20 INPUT Q
   30 CLEAR O
   40 FOR Z=O TO V STEP Q; Y=V-Z
   50   MOVE O,Z; DRAW Y,O
   60   MOVE Y,V; DRAW V,Z
   70 NEXT Z
   80 END

The value of Q typed in should be between 2 and 9 for best results; V determines the size of the square that is drawn. The program works best when V is a multiple of Q.

5.2 DO...UNTIL Loops

ATOM BASIC provides an alternative pair of loop-control statements: DO and UNTIL. The UNTIL statement is followed by a condition, and everything between the DO statement and the UNTIL statement is repeatedly executed until the condition becomes true. So, to print 256 exclamation marks in yet another way write:

   10 I=0
   20 DO
   30   I=I+1
   40   PRINT "!"
   50 UNTIL I=256
   50 END

Again, the statements inside the DO...UNTIL loop may be indented to make the structure clearer.

The DO...UNTIL loop is most useful in cases where a program is to carry on until certain conditions are satisfied before it will stop. To illustrate, the following program prompts for a series of numbers, and adds them together. When a zero is entered the program terminates and prints out the sum:

   10 S=0
   20 DO INPUT J
   30    S=S+J
   40 UNTIL J=0
   50 PRINT "SUM =", S
   60 END

Note that a statement may follow the DO statement, as in this example.

5.2.1 Greatest Common Divisor

The following simple program uses a DO...UNTIL loop in the calculation of the greatest common divisor (GCD) of two numbers; i.e. the largest number that will divide exactly into both of them. For example, the GCD of 26 and 65 is 13. If the numbers are coprime the GCD will be l.

     1 REM Greatest Common Divisor
    80 INPUT A,B
    90 DO A=A%B
   100 IF ABS(B)>ABS(A) THEN T=B; B=A; A=T
   120 UNTIL B=0
   130 PRINT "GCD =" A'
   140 END

Description of Program:
80        Input two numbers
90        Set A to remainder when it is divided by B
100       Make A the larger of the two numbers
120       Stop when B is zero
130       A is the greatest common divisor.

Variables:
A,B - Numbers
T - Temporary variable

Program size: 137 bytes

The method is known as Euclid's algorithm, and to see it working insert a line:

   95 PRINT A,B'

The ABS functions ensure that the program will work for negative, as well as positive, numbers.

5.2.2 Successive Approximation

The DO...UNTIL loop construction is especially useful for problems involving successive approximation, where the value of a function is calculated by obtaining better and better approximations until some criterion of accuracy is met.

The following iterative program calculates the square root of any number up to about 2,000,000,000. Also shown is the output obtained when calculating the square root of 200,000,000:

   10 REM Square Root 
   20 INPUT S
  100 Q=S/2
  110 DO Q=(Q+S/Q)/2
  120 UNTIL (Q-1)*(Q-1)<S AND (Q+1)*(Q+1)>S
  130 PRINT Q
  140 END
Description of Program:
20	Input number
100	Choose starting value
110	Calculate next approximation
120	Carry on until the square lies between the squares of the
        numbers either side of the root.
130	Print square root.

Variables:
Q - Square root
S - Number
Program size: 118 bytes Sample run:

>RUN
?200000000
   14142>

5.3 Nested Loops

FOR...NEXT and DO...UNTIL loops may be nested; the following example will print the squares, cubes, and fourth powers of the numbers 1 to 15 in a neat table:

    1 REM Powers of Numbers
    5 PRINT"        X     X^2"
    8 PRINT"      X^3     X^4"
   10 FOR N=1 TO 15
   20   J=N
   30   FOR M=1 TO 4
   40     PRINT J; J=J*N
   50   NEXT M
   60 NEXT N
   70 END

The statements numbered 20 to 50 are executed 15 times, for every value of N from 1 to 15. For each value of N the statements on line 40 are executed four times, for values of M from 1 to 4. Thus 15*4 or 60 numbers are printed out.

5.3.1 Mis-Nested Loops

Note that loops must be nested correctly. The following attempt at printing out 100 pairs of numbers will not work:

   10 FOR A=1 TO 10
   20 FOR B=1 TO 10
   30 PRINT A,B
   40 NEXT A
   50 NEXT B

The program will, if RUN, give an error (ERROR 230). The reason for the error will become clear if you try to indent the statements within each loop, as in the previous example.

5.4 WAIT Statement

ATOM BASIC includes an accurate timing facility, derived from the main CPU clock. To understand the operation of the WAIT statement, imagine that the ATOM contains a clock which 'ticks' sixty times a second. The WAIT statement causes execution to stop until the next clock tick. Thus it automatically synchronises the program to an accurate time.

The WAIT statement makes it a simple matter to write programs to give any required delay. For example, the following program gives a delay of 10 seconds:

      FOR N=1 TO 10*60; WAIT; NEXT N

You are perhaps wondering why WAIT does not just give a delay of 1/60 second, rather than waiting for the next clock tick. The reason is that if only a delay function were provided, you would have to know exactly how long the other statements in the loop took to execute if you wanted accurate timinq. In fact, with the WAIT function, all you need to do is to ensure that the statements in the loop take less than 1/60th. of a second, so as not to miss the next tick.

5.4.1 Digital Clock

The following digital clock displays the time as six digits in the top left-hand corner of the screen.

   10 REM Digital Clock
   20 INPUT "TIME" H,M,S
   30 PRINT $12; ?#El=0
   40 T=((H*100)+M)*100+S
   50 DO FOR S=l TO 55; WAIT; NEXT S
   60 PRINT $30,T; T=T+1
   70 IF T%100=60 THEN T=T+40
   80 IF T%10000=6000 THEN T=T+4000
   90 UNTIL 0

Description of Program:
20	Input the starting time
30	Clear screen; turn off cursor
40	Set up time as 6-digit number
50	Use up rest of a second
60	Print T in top left-hand corner of screen
70-80     Update minutes and hours

Variables:
H - Hours
M - Minutes
S - Seconds
T - Six-digit number representing time

Program size: 216 bytes

To turn the cursor back on after running this program type a form-feed; i.e. CTRL-L.

5.4.2 Reaction Timer

The following reaction-timer program uses WAIT to calculate your reaction time, and prints out the time in centiseconds (i.e. hundredths of a second) to the nearest 2 centiseconds. It blanks the screen, and then, after a random delay, displays a dot at a random place on the screen. When you see the dot you should press the SHIFT key as quickly as possible; the program will then display your reaction time.

    1 REM Reaction Timer
   10 CLEAR 0
   20 X=ABS(RND)%64; Y=ABS(RND)%48
   30 FOR N=l TO ABS(RND)%600+300
   40 WAIT; NEXT N
   50 MOVE X,Y; DRAW X,Y
   60 T=0
   70 DO T=T+1; WAIT
   80 UNTIL ?#B001<>#FF
   90 PRINT "REACTION TIME ="
   100 PRINT T*10/6, " CSEC." '
   110 IF T>18 PRINT "WAKE UP!" '  
   120 END

Description of Program:
20        Choose random X,Y coordinates for point on screen.
30-40     Wait for random time between 6 and 9 seconds.
50        Plot point at X,Y
60-70     Count sixtieths of a second
80        #B001 is the address of the input port to which the SHIFT key
          is connected; the contents of this location are #FF until 
          the SHIFT key is pressed.
90-100    Print reaction time converted to centiseconds.
110       If appalling reactions, print message.

Variables:
N - Counter for random delay
T - counter in sixtieths of a second for reaction time
X,Y - random coordinates for point on screen.

Program size: 273 bytes

Next chapter