%%HP: T(3)A(D)F(.); @ by Dave Vomocil \<< @ Each mixed number is a list of size three. 3 \->LIST 4 ROLLD 3 \->LIST SWAP @ Check that both denom's are non-zero. DUP2 3 GET SWAP 3 GET AND IF NOT THEN 440 .5 BEEP "PLUS: zero in denom" 1 DISP 1 FREEZE ELSE 64 R\->B 131 R\->B BLANK PICT STO @ Blank a 64X131 PICT @ Display the first addend SWAP 0 DISPL SWAP @ Now figure out where to place the + sign 1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B 20 R\->B 2 \->LIST PICT SWAP " + " 3 \->GROB @ GOR the + sign into PICT GOR @ And now the second addend 15 DISPL 25 R\->B 30 R\->B 2 \->LIST 85 R\->B 30 R\->B 2 \->LIST LINE @ ADD the two mixed numbers and DISPL the sum. @ Compute LCM of denominators DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer carry \<< @ Compute numerator of fraction 1 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * 'numer' STO @ Compute numerator of fraction 2 and add SWAP 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * numer + 'numer' STO @ Check for carry and reduce fraction part numer lcm / IP 'carry' STO numer lcm MOD 'numer' STO numer lcm GCD DUP @ Reduce if non-zero GCD DUP IF THEN numer SWAP / 'numer' STO lcm SWAP / 'lcm' STO ELSE DROP2 END @ Add the whole numbers and the carry 1 GET SWAP 1 GET + carry + @ Form the mixed number list numer lcm 3 \->LIST \>> @ end of scope of lcm numer and carry @ DISPL the result 32 DISPL @ Convert the list to elements on the stack. OBJ\-> DROP END \>> 'PLUS' STO \<< @ Convert elements on the stack to two lists 3 \->LIST 4 ROLLD 3 \->LIST SWAP @ Check that both denom's are non-zero. DUP2 3 GET SWAP 3 GET AND IF NOT THEN 440 .5 BEEP "SUBTR: zero in denom" 1 DISP 1 FREEZE ELSE 64 R\->B 131 R\->B BLANK PICT STO @ Blank a 64X131 PICT @ Display the first minuend SWAP 0 DISPL SWAP @ Now figure out where to place the - sign 1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B 20 R\->B 2 \->LIST PICT SWAP " - " 3 \->GROB @ GOR the + sign into PICT GOR @ And now the second subtrahend 15 DISPL 25 R\->B 30 R\->B 2 \->LIST 85 R\->B 30 R\->B 2 \->LIST LINE @ ADD the two mixed numbers and DISPL the sum. @ Compute LCM of denominators DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer borrow \<< @ Compute numerator of fraction 1 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * 'numer' STO @ Compute numerator of fraction 2 SWAP 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * numer SWAP - DUP @ Determine if we need to borrow WHILE 0 < REPEAT lcm + DUP 'borrow' 1 STO+ END 'numer' STO @ Reduce fraction part numer lcm GCD DUP @ Reduce if non-zero GCD DUP IF THEN numer SWAP / 'numer' STO lcm SWAP / 'lcm' STO ELSE DROP2 END @ Subtract the whole numbers SWAP 1 GET SWAP 1 GET - borrow - @ Form the mixed number list numer lcm 3 \->LIST \>> @ end of scope of lcm numer and carry @ DISPL the result 32 DISPL @ Convert the list to elements on the stack OBJ\-> DROP END \>> 'SUBTR' STO \<< @ Compute LCM of denominators DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer carry \<< @ Compute numerator of fraction 1 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * 'numer' STO @ Compute numerator of fraction 2 and add SWAP 2 GETI 3 ROLLD GETI SWAP DROP lcm SWAP / 3 ROLL * numer + 'numer' STO @ Check for carry and reduce fraction part numer lcm / IP 'carry' STO numer lcm MOD 'numer' STO numer lcm GCD DUP @ Reduce if non-zero GCD DUP IF THEN numer SWAP / 'numer' STO lcm SWAP / 'lcm' STO ELSE DROP2 END @ Add the whole numbers and the carry 1 GET SWAP 1 GET + carry + @ Form the mixed number list numer lcm 3 \->LIST \>> @ end of scope of lcm numer and carry \>> 'ADD' STO \<< @ Convert the elements on the stack to two lists. 3 \->LIST 4 ROLLD 3 \->LIST SWAP @ Check that both denom's are non-zero. DUP2 3 GET SWAP 3 GET AND IF NOT THEN 440 .5 BEEP "SUBTR: zero in denom" 1 DISP 1 FREEZE ELSE 64 R\->B 131 R\->B BLANK PICT STO @ Blank a 64X131 PICT @ Display the first mmultiplier SWAP 0 DISPL SWAP @ Now figure out where to place the * sign 1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B 20 R\->B 2 \->LIST PICT SWAP " * " 3 \->GROB @ GOR the + sign into PICT GOR @ And now the second multiplier 15 DISPL 25 R\->B 30 R\->B 2 \->LIST 85 R\->B 30 R\->B 2 \->LIST LINE @ Multiply the two mixed numbers and DISPL the sum. @ Convert the two mixed numbers to improper fractions. 3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL + SWAP DROP 2 SWAP PUTI DROP SWAP 3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL + SWAP DROP 2 SWAP PUTI DROP @ Multiply numerators and denominators 2 GETI 4 ROLLD GET 3 ROLLD 2 GETI 3 ROLLD GET SWAP 4 ROLL * 3 ROLLD * \-> denom numer \<< denom numer GCD @ Reduce if non-zero GCD DUP IF THEN DUP numer SWAP / 'numer' STO denom SWAP / 'denom' STO ELSE DROP END @ Convert from an improper fraction to a mixed number numer denom / IP numer denom MOD denom @ Form the mixed number list 3 \->LIST \>> @ end of scope of denom and numer @ DISPL the result 32 DISPL @ Convert the list to three elements on the stack OBJ\-> DROP END \>> 'MULTI' STO \<< @ Convert elements on the stack to two lists. 3 \->LIST 4 ROLLD 3 \->LIST SWAP @ Check that both denom's are non-zero. DUP2 3 GET SWAP 3 GET AND IF NOT THEN 440 .5 BEEP "DIVI: zero in denom" 1 DISP 1 FREEZE ELSE 64 R\->B 131 R\->B BLANK PICT STO @ Blank a 64X131 PICT @ Display the dividend SWAP 5 DISPL SWAP @ Now figure out where to place the divide sign 1 GETI SWAP DROP \->STR SIZE 3 + 6 * NEG 65 + R\->B 25 R\->B 2 \->LIST PICT SWAP " / " 3 \->GROB GOR @ And now the divisor 20 DISPL 25 R\->B 35 R\->B 2 \->LIST 85 R\->B 35 R\->B 2 \->LIST LINE @ Multiply the two mixed numbers and DISPL the sum. @ Convert the two mixed numbers to improper fractions. 3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL + SWAP DROP 2 SWAP PUT SWAP 3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL + SWAP DROP 2 SWAP PUT SWAP @ Invert the quotient 3 GETI 3 ROLLD DROP 2 GETI PUT SWAP 2 SWAP PUT @ Multiply numerators and denominators 2 GETI 4 ROLLD GET 3 ROLLD 2 GETI 3 ROLLD GET 4 ROLL * 3 ROLLD * \-> denom numer \<< denom numer GCD @ Reduce if non-zero GCD DUP IF THEN DUP numer SWAP / 'numer' STO denom SWAP / 'denom' STO ELSE DROP END @ Convert from an improper fraction to a mixed number numer denom / IP numer denom MOD denom @ Form the mixed number list 3 \->LIST \>> @ end of scope of denom and numer @ DISPL the result 37 DISPL @ Convert the list to elements on the stack OBJ\-> DROP END \>> 'DIVI' STO @ Computes the lcm using the @ lcm(m,n) * gcd(m,n) = m * n \<< DUP2 AND IF @ Check for 0 in the arguments. THEN @ Compute m * n then the GCD and finally divide DUP2 * 3 ROLLD GCD / ELSE @ Else return a zero DROP2 0 END \>> 'LCM' STO @ This uses Euclid's algorithm to compute the gcd. @ Euclid's algorithm as Stan remembered it is: @ If you want the gcd of m and n, then iterate the following: @ First express m as q0*n + r0 @ then express n as q1*r0 +r1 @ iterate rn as q(n+2)*r(n+1) + r(n+2) @ when r(n+2) == 0 then r(n+1) is the gcd. \<< DUP2 AND @ Check for a 0 in the arguments IF THEN @ Apply Euclid's algorithm DO DUP 3 ROLLD MOD DUP UNTIL NOT END DROP ELSE @ Return a zero if a 0 was in the arguments. DROP2 0 END \>> 'GCD' STO \<< 0 DUP \-> row len midp @ Grab the display row to use @ and set up a couple locals \<< @ First handle the whole number @ Display the whole number only if it is non-zero @ or the fraction is zero 1 GETI 3 ROLLD GETI SWAP DROP NOT 3 ROLL OR IF THEN 1 GETI \->STR DUP SIZE 'len' STO @ save the length 3 \->GROB @ Get the whole number to a GROB PICT SWAP @ GOR it into the PICT 65 len 6 * - R\->B row 4 + R\->B 2 \->LIST SWAP GOR ELSE 2 END @ Now for the fraction part. @ First check the numerator. If it's zero we're done. @ Otherwise ... @ computer the width of the fraction GETI DUP IF THEN \->STR SIZE 'len' STO GETI \->STR SIZE len MAX 4 * 2 / 'midp' STO DROP 2 @ Now place the numerator in the PICT GETI \->STR DUP SIZE 'len' STO @ Save the length 1 \->GROB PICT SWAP len 2 * NEG midp + 66 + R\->B row R\->B 2 \->LIST SWAP GOR @ Now the fraction bar 65 R\->B row 6 + R\->B 2 \->LIST 65 midp 2 * + R\->B row 6 + R\->B 2 \->LIST LINE @ Finally the denominator GETI \->STR DUP SIZE 'len' STO 1 \->GROB PICT SWAP len 2 * NEG midp + 66 + R\->B row 8 + R\->B 2 \->LIST SWAP GOR ELSE DROP END @ Display the result 0 R\->B DUP 2 \->LIST PVIEW 3 FREEZE DROP @ DROP the GETI index \>> @ end scope of row and a couple locals \>> 'DISPL' STO @ Displays the 'fraction' on the top of the stack \<< 3 \->LIST DUP 3 GET IF NOT THEN 440 .5 BEEP "DISP: zero in denom" 1 DISP 1 FREEZE ELSE 64 R\->B 131 R\->B BLANK PICT STO 20 DISPL OBJ\-> DROP END \>> 'DPLAY' STO \<< 6 ROLL 6 ROLL 6 ROLL \>> 'SWAPR' STO { S DPLAY 35.2 SWAPR 36.2 DIVI 65.1 MULTI 75.1 SUBTR 85.1 PLUS 95.1 } STOKEYS