Post Reply 
(49G, 49g+ & 50g) ZREV: Speedily Reverse Digits of Integer
03-14-2018, 02:55 AM (This post was last modified: 03-14-2018 03:15 AM by DavidM.)
Post: #6
RE: (49G, 49g+ & 50g) ZREV: Speedily Reverse Digits of Integer
(03-14-2018 01:17 AM)rprosperi Wrote:  But as I said, I look forward to reading David's reply.

I may disappoint you, Bob. Smile Note that this response has been affected by the fact that I've been up for over 40 hours now with no sleep. While it may take some work to follow, I promise that there is actually some truth contained herein.

Rather than addressing the structural and syntactical components of SysRPL and Saturn code (which any 12-year-old with 16 years of experience could do Smile), I'll attempt to paraphrase what I believe the two different programs do.

Gerald's:

This one makes use of the core of one of the commands available in the "development menu" (specifically →H, the first command available in menu 256). That command converts any RPL object into a string that contains the hex representation of the actual data that is stored internally for the object.

To see examples of this command, first execute 256 MENU in RPN mode. You'll see a menu that starts with →H. Now, place any object on the stack, then press the F1 key (which maps to →H). You'll see the hex representation of that object as the result. Now try to convert some exact integers (reals are also interesting, but not as important for the discussion du jour). You'll find that the exact integers are converted to a string that always starts with "41620..." (which is the defined prologue for an exact integer, reversed), then has 5 more characters that represent the length (in nibbles) of everything except that first "41620" (reversed), then the digits of the integer in reverse order of the integer in question, then either a 0, a 9, or nothing (if you convert 0). That last digit represents the sign of the integer (0=+, 9=-). The astute reader may notice that I've used the word "reversed" (or some form of it) quite a bit here. This is not an accident. Stare at these hex representations of exact integers for a little while and I promise you'll see why this penchant for reversing is helpful here.

After determining that you provided an exact integer argument, Gerald's program simply converts it to hex form (as a string), then extracts the digits needed for the result (as a string), then converts that string back to an integer. He essentially always starts at the 11th character and takes everything up to (and including) the penultimate character as that substring. If you look at the hex data for the exact integer 0, you'll see why that one doesn't work.

David's:

I'll ignore the part of the code that "overloads" specific functionality for different object types, as that fits squarely into the "structural/syntactical" realm which is beyond the scope of what I'm trying to convey here. Smile

Given an exact integer, my program starts off by making a copy of what it was given. This is important because the "reversing" of the digits in this program is actually performed "in place" for the raw object, so a copy must be made to fulfill the calculator's need to still support things like Last Stack, UNDO, LASTARG, etc. By "etc.", I mean some fairly esoteric but important things such as "if you directly change one object that is duplicated on the stack, all of the duplicates will show the same edited version". This is not what most people expect to happen on their calculators, so it should be avoided unless you simply like to write programs that confuse people.

Since we already know the structure of the exact integer in memory (see above), we can make an important assumption based on the length of the object: if the length (less 6) is less than 2, then we don't have to do anything at all. Yay! Go Directly to GO, collect $200. We're done! Notice that this logic automatically handles 0 in the same fashion as all other single-digit integers, despite the fact that it has a severe attitude about its independent representation ("I'm 0 -- I don't need no stinkin' sign digit!").

If the count of the digits (length-6) is 2 or more, then "a-swapping we will go, a-swapping we will go, hi ho the derry oh, a-swapping we will go!". The core of the subroutine then simply uses a time-honored approach to performing a reversal. Start with the first and last digits, swap them, then move "inward" to the next two digits and repeat! (a total of length DIV 2 times). A happy bi-product of this approach is that an odd number of digits ignores that central digit, which of course can't be swapped with itself without a visit to a psychiatrist.

If you're still paying attention (and I'm quite certain very few of you are), then you may have noticed that I've used 6 several times as an offset to the length. Why is that???? Here's a hint: that 6 can be thought of as 5+1. 1 is the sign digit. What is the 5? See if you can figure it out.

Note that by only swapping the digits (and ignoring the sign), we end up carrying the sign to the result without even trying. Those are my favorite kinds of programming results. We get to claim a feature ("I added support for preserving the sign!") simply by not doing anything at all. It's hard work, but somebody has to do it.
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: (49G, 49g+ & 50g) ZREV: Speedily Reverse Digits of Integer - DavidM - 03-14-2018 02:55 AM



User(s) browsing this thread: 1 Guest(s)