Program: LONGOPS Author: Paul Pollack (paulp@televault.com) Date: June 19, 1996 Synopsis: LONGOPS performs a series of operations and returns the exact result where precision would normally be lost. Instructions: If you've uudecoded the listing below, load up the Graph-Link software/LINK85 and ungroup LONGOPS; you should now have L2SD, LONGC, MULT, PWR, and FCTRL. LONGC and L2SD are "subroutines" necessary for the successful running of PWR, FACT and MULT; MULT has changed since version 1.0 and now takes full advantage of LONGC and L2SD, saving about 700 bytes. Run either PWR, MULT, or FCTRL; you should be prompted for a number. If you're running MULT, enter the number using as many digits as you'd like- it's stored as a string and all the computations are done using lists, so you could theoretically work with numbers hundreds of digits long. If you're working with PWR or FCTRL you'll have to use numbers that the TI can normally work with. In PWR, a (in a^b) must be less than about (4.473e6). How long your results can be depends on the amount of free memory in your calculator. === Bugs/features: The programs above were meant for figuring out problems which would be too tedious to work out by hand. Ironically, in their design, the simple problems are either not done, or done incorrectly. MULT will not multiply two one digit numbers; PWR does not handle the trivial cases 1^x, 0^x or x^0 and FCTRL doesn't do 0! === Limitations: Many of the limitations (such as the limit on the number of digits the two numbers you multiply can be) vary depending on the calculator's memory. Others do not -- a^b in PWR as well as n! in FCTRL must not exceed 1e999. === Algorithm (for those who care): I simulate long integers by storing them internally as a list of digits. Let me cover the algorithm used in MULT first: the two numbers the user inputs are translated from strings into lists by a rather inefficent (but working) algorithm. I simply go through the whole string, check each "number" in the string to see what digit it corresponds to and then place it in the list. Say my two lists look like this (a very simple case, admittedly...): [ 1 1 ] [ 1 3 ] I treat the two lists as polynomials -- multiplying using Richard Homard's excellent algorithm, I get another list [ 1 4 3 ]; because all the numbers in the list are single digits, I've got lucky and 143 is my final answer. I could get unlucky, though, and get a product like [ 1 26 21 12 31 ]. Since I'm evaluating the polynomial at 10, I can implement a simple algorithm, going from right to left that takes the number (div 10), adds it to the number in front and then replaces the number by the number mod 10. I go through the whole list until I finish... This is the basis for LONGC, which MULT (in this version) uses. Continuing with [ 1 26 21 12 31 ], I get: [ 1 26 21 15 1], then [ 1 26 22 5 1], then [ 1 28 2 5 1], then [ 3 8 2 5 1] Since all my numbers are single digits, 38251 is the answer I'm looking for -- all I have to do is change the number from a list to a string and I'm done -- this is what L2SD (List 2 String and Display) does, but that came long after MULT as well. The algorithm used in PWR and FCTRL is similar: they both rely on the fact that to multiply a number stored this way, all I have to do is multiply each of its elements by the desired quantity and then use the above list cleaning up algorithm on it. For example, to multiply 3921 by 22, I do something like this: [ 3 9 2 1 ] * 22= [ 66 198 44 22 ]; [ 66 198 46 2 ]; [ 66 202 6 2]; [ 86 2 6 2]; [ 8 6 2 6 2] I then just have to run L2SD and I have my number! PWR just does this a number of times: to calculate 8 cubed, all I do is find out how many digits 8^3 has by truncating the log of the answer and adding one. Note that my reasoning isn't circular [I can already hear people saying "How's he taking the log of the answer when he doesn't know it!?"]-- I'm taking the log of the answer the calculator gets normally, which in many cases will be missing significant digits. Anyway, here goes: [ 0 0 8 ] ( I create a list with 3 (or more) places since 8^3 has 3 digits. I then place the number in the last spot and multiply by 8 the remaining (power-1) times -- in this case, 2. ) [ 0 0 64] ( *8 and then LONGC here to clean it up ) [ 0 6 4 ] ( cleaned up output ) [ 0 48 32 ] ( multiplied by 8 again ) [ 5 1 2 ] ( cleaned up ) FCTRL uses a similar process which you should be able to guess by now... you're also probably wondering why I clean-up the output after each time. I was wondering that as well, and that's why I don't. In the programs below, I only clean up the list when the numbers in them good have significant digits lost when performing the multiplication. To understand this, consider below: Say I was working with a stupid machine that could only handle 4 digits in a list and I want to take 8^5. I have [ 0 0 0 0 8 ] --> [ 0 0 0 0 64 ] [ 0 0 0 0 512 ] [ 0 0 0 0 4096 ] -- Ahhhh! I can't go on any further because if I multiply by 8 again, I'm just going to lose significant digits! I just clean up the list right now to prevent it... [ 0 4 0 9 6 ] [ 0 32 0 72 48 ] (after cleaning up): [ 3 2 7 6 8 ] This does bring some limitations into it; since the TI-85 only integers up to about 2e13 without loss of significant digits, the base of the number I'm multiplying by can't be any bigger than its (2e13's) square root without risking some danger -- hence the 4.2e6 limitation. Hence, to make 2^300 execute faster, you could use 2^20 as your number and 15 as your power, but you couldn't use 2^30 as your number with 10 as your power. That about wraps it up. Drop me a note with any questions or comments. === If you find a bug in any of these programs, I'll issue a new version immediately. Feel free to write me or use any of my routines in a program of your own -- all I would like is an e-mail message telling me of the project and just a small mention in your documentation. BTW, DOS versions of FCTRL and PWR are available and handle numbers up to approx. 16200 digits long. If you're interested, just drop me a message with the subject: LONGOPS DOS request, or something of that nature. Thanks! -- Paul Pollack paulp@televault.com