From madler@piglet.caltech.edu Mon Nov 12 17:13:44 1990 From: madler@piglet.caltech.edu (Mark Adler) Newsgroups: comp.sys.handhelds Subject: Breaking out of loops on the HP-48SX Date: 11 Nov 90 00:27:58 GMT Organization: California Institute of Technology, Pasadena Nntp-Posting-Host: piglet.caltech.edu I just discovered a technique that I thought I'd share. The HP-48SX appears to lack a way to break out of loops. But appearances can be deceiving. There is a kludgey way to do it. You can put the loop in an IFERR statement, and then divide by zero or some such thing to cause an error. This appears to cleanly exit the loop (or loops). As an example of this tehcnique, here is a program (FACNUM) which will take a whole number and return its prime factorization as a list of primes, repeated if necessary. I wanted to avoid having the inner loop do two tests, so it could be a simple FOR loop, and so the loop exit is done inside IF statements with a divide by zero. A note to HP: please include a throw/catch operation for exiting loops on the next calculator (48SY? 49?). The code to handle cleaning up leftover constructs appears to already be there for IFERR. Thanks. Mark Adler madler@piglet.caltech.edu program follows ... %%HP: T(3)A(R)F(.); @ FACNUM (BYTES = 277.5, #74FFh) @ Given an integer, return its prime factorization as a list. @ For example, 16353 FACNUM returns { 3 3 23 79 }. \<< @ initialize factor list { } SWAP @ For this part of the program the stack is: n factorlist, where the two are @ kept so that the product of the list times n is the original integer. @ factor out 2's WHILE DUP 2 MOD NOT REPEAT 2 / SWAP 2 + SWAP END @ factor out 3's WHILE DUP 3 MOD NOT REPEAT 3 / SWAP 3 + SWAP END @ start factor search at 5 5 @ The stack is now: k n factorlist, where the second two are maintained as @ before, and k is the largest 5 mod 6 integer less than or equal to the @ last factor found (execpt initially when it is set to 5). @ search from k to sqrt(n) for factors---k must be 5 mod 6 WHILE OVER 1 \=/ REPEAT @ do while n is not one OVER \v/ FLOOR @ go up to the floor of the square root IFERR @ (divide by zero used as a loop breaker) FOR i @ look at factors that are 1 and 5 mod 6 IF DUP i MOD NOT THEN i 0 / END @ if 5 mod 6 divides n, then cause error IF DUP i 2 + MOD NOT THEN i 2 + 0 / END @ if 1 mod 6 divides n, then cause error 6 STEP THEN DROP @ got an error---trash the zero ELSE DUP @ end of loop---n divides n END @ after this, stack is: factor n factorlist ROT OVER + ROT ROT @ add factor to list (factor n factorlist') SWAP OVER / SWAP @ divide out divisor (factor n' factorlist') DUP 6 MOD 5 - 2 / + @ set k' to largest 5 mod 6 <= divisor END @ find next factor (k' n' factorlist') @ return list, dropping n and k DROP2 \>> From edp@ipl31.enet.dec.com) Mon Nov 12 17:13:58 1990 From: edp@ipl31.enet.dec.com (Eric Postpischil (Always mount a scratch monkey.)) Newsgroups: comp.sys.handhelds Subject: Re: Breaking out of loops on the HP-48SX Date: 11 Nov 90 18:59:46 GMT Reply-To: edp@ipl31.enet.dec.com (Eric Postpischil (Always mount a scratch monkey.)) Organization: Digital Equipment Corporation In article <1990Nov11.002758.4933@nntp-server.caltech.edu>, madler@piglet.caltech.edu (Mark Adler) writes: > You can put the loop in an IFERR statement, and then divide by > zero or some such thing to cause an error. To generate an error, you can use the DOERR command. -- edp From madler@piglet.caltech.edu Mon Nov 12 17:14:09 1990 From: madler@piglet.caltech.edu (Mark Adler) Newsgroups: comp.sys.handhelds Subject: Re: Breaking out of loops on the HP-48SX Date: 11 Nov 90 23:15:33 GMT Organization: California Institute of Technology, Pasadena Nntp-Posting-Host: piglet.caltech.edu Eric Postpischil points out: >madler@piglet.caltech.edu (Mark Adler) writes: > >> You can put the loop in an IFERR statement, and then divide by >> zero or some such thing to cause an error. > >To generate an error, you can use the DOERR command. > > > -- edp Thanks. A "0 DOERR" is much cleaner, in that it does not affect ERRN or ERRM (which records the last error). Mark Adler madler@piglet.caltech.edu