Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!cs.utexas.edu!sun-barr!apple!portal!cup.portal.com!sjthomas From: sjthomas@cup.portal.com (Stephen J Thomas) Newsgroups: comp.sys.handhelds Subject: DEC2FRAC-II for the HP48SX Message-ID: <40605@cup.portal.com> Date: 27 Mar 91 05:29:25 GMT References: <12222@ccncsu.ColoState.EDU> <27efcf56:1772.1comp.sys.handhelds;1@hpcvbbs.UUCP> Organization: The Portal System (TM) Lines: 124 *** HP 48SX *** First, congratulations to Joe Horn for his recently posted algorithm which improves on the ->Q function of the HP48. Joe's program (which he calls DEC2FRAC, and I call TO.Q, requires two inputs: 2: real number to be "fractionalized" 1: maximum value of the denominator By specifying the maximum denominator, the user can greatly control the output of the program. However, if you're performing many computations which all involve the same maximum denominator, it is tiresome to have to repeatedly re-enter this denominator. I've written a small calling program which allows you to maintain the same denominator. This is done by entering the maximum denominator only when you wish to change it -- and in that case, it must be the only element in a list in level one. That is, on executing the calling program (which I call TO.Q2), if level 1 contains a list, the value in the list is stored into a global variable named 'denom'. Then 'denom' is recalled to level 1, and execution dumps into TO.Q. If, on executing TO.Q2, level 1 contains a real number (actually, anything other than a list), 'denom' is recalled to level 1, and execution continues with TO.Q. Example: What are the best fractional approximations for e and the square root of 2 ( v/2 ) with a maximum denominator of 100? Solution: First do e: 1 EXP { 100 } TO.Q2 ==> '193/71' Now do v/2: Since the max denom is the same, just enter v/2: 2 v/ TO.Q2 ==> '140/99' NOTES: 1. There is not much error-checking for valid inputs in these routines. Perhaps an internal RPL version could do this without slowing down execution much (Joe?). 2. Storing to and recalling 'denom' are subject to all the rules of the directory structure: "You can RCL from anyplace, but you STO where you sit." That is, you can use (recall) 'denom' if it's in a parent directory, but if you create a new value for 'denom', it's stored in the current subdirectory. 3. I've assigned Joe's main program to the ->Q position on my 48, and TO.Q2 to the ->NUM position, so both are readily available. 4. Again, all credit for DEC2FRAC (or TO.Q) goes to Joe Horn. Following TO.Q2, I've listed Joe's program, in case you missed it. %%HP: T(3)A(D)F(.); @ @ TO.Q2 -- Calling program for TO.Q (or DEC2FRAC, by Joe Horn) @ @ Input: 2: real number to be converted to a fraction @ 1: list containing maximum denominator @ or @ 1: real number to be converted to a fraction @ (using previous maximum denominator) @ \<< DUP TYPE IF 5 == @ Does level 1 contain a list? THEN OBJ\-> DROP @ If so, then extract the max denom and 'denom' STO @ STOre it END denom @ Recall max denom to level 1 TO.Q @ Dump to TO.Q -- change this to DEC2FRAC \>> @ if you use the original name Note: My first version of TO.Q2 used a binary value rather than a list in level 1 to specify a new max denom. But -- my 48 is usually in HEX mode -- I often forgot to add the 'd' to the binary. If you prefer using a binary value, change: 5 to 10 OBJ\-> DROP to B\->R Stephen J Thomas sjthomas@cup.portal.com akcs.sjthomas@hpcvbbs.uucp %%HP: T(3)A(D)F(.); @ TO.Q (or DEC2FRAC) by Joseph K. Horn \<< DUP2 IF 1 > SWAP FP AND THEN \-> f c \<< 0 1 f WHILE OVER c < OVER AND REPEAT INV DUP FP 4 ROLLD IP OVER * ROT + ROT END DROP DUP2 c IF DUP2 > THEN - OVER / CEIL * - ELSE 3 DROPN END DUP2 1 2 START DUP f * 0 RND SWAP / f - ABS SWAP NEXT IF > THEN SWAP END DROP DUP f * 0 RND SWAP \>> IF DUP ABS 1 > THEN # 5603Eh SYSEVAL ELSE DROP END ELSE DROP END \>>