Do you frequently convert between number bases? I do and, whilst it’s getting pretty easy to do a lot in one’s head, there are times when it’d be nice to just type in a value and press “Convert”. Here’s a solution:
The program defines three buttons A, B and C. In the hp67u, they look like this:
CARD 11 Title: Base Conversion A: b B: 10->b C: b->10 ...
The idea is simple: you specify a base and then convert to or from that base and base 10. No, that isn’t a limitation – because you can change the base and continue. For example:
2 A 1011 C (gives 11 base 10), 8 A Rv (gets 11 back) B (gives 13 base 8)
A – Set the base
It’s really three simple programs and they’re all translatable to other calculators. Here’s the “A” one:
001: 31 25 11 : f LBL A 002: 33 11 : STO A 003: 01 : 1 004: 00 : 0 005: 32 81 : g x>y 006: 22 00 : GTO 0 007: 32 51 : g x=y 008: 22 00 : GTO 0 009: 32 54 : g x^2 010: 31 25 00 : f LBL 0 011: 33 12 : STO B 012: 35 53 : h Rv 013: 35 22 : h RTN
This is pretty straight forward. The main thing it’s doing is storing the base. In the HP-67, I’m using storage register A because that’s a good place to store something related to the “A” key. Any other spot would do too.
The other thing here is I’m setting storage register B to 10 or to 100. If I can fit a digit in the specified base in a single display digit, I use 10 here. If I’m going to need more than one display digit to show a base digit, I use 100 here. The idea is this: binary I can show like “1011001”, octal I can show as “37776” and decimal I can show like “789”; but hexadecimal I’ll need to show as “11515” (for 1FF). You enter things the same way.
The combination of conditionals seemed a neat way of testing for base <= 10 and keeping 10 in the X register given that the conditional choices on the HP-67 have some limitations.
If you enter a negative base, a fractional base or one that needs three digits (eg base 101); the program will not cope well. I haven’t added in bounds checks. Please treat the program nicely.
B – Base 10 to Base b
For the “B” program (10->b), it looks like this:
014: 31 25 12 : f LBL B 015: 00 : 0 016: 35 33 : STO I 017: 33 00 : STO 0 018: 35 53 : h Rv 019: 31 25 01 : f LBL 1 020: 34 11 : RCL A 021: 81 : / 022: 41 : ENTER 023: 32 83 : g FRAC 024: 34 11 : RCL A 025: 71 : x 026: 31 24 : f RND 027: 34 12 : RCL B 028: 35 34 : RCL I 029: 35 63 : h y^x 030: 71 : x 031: 33 61 00 : STO + 0 032: 31 34 : f ISZ 033: 35 53 : h Rv 034: 31 83 : f INT 035: 31 81 : f x>0 036: 22 01 : GTO 1 037: 34 00 : RCL 0 038: 35 22 : h RTN
The first few steps store 0 in the final value (storage register 0) and in a counter (storage register I, “h STI” on the keyboard). The rolldown (Rv) restores the value we are about to convert.
Label 1 is the main loop for this program. The process is fairly standard: you divide by the base and save the remainder as the least significant digit, and then repeat the process for the next least significant digit until there is nothing left to convert.
Steps 020-026 do the divide and work out the remainder. (“f RND” rounds the result so we always end up with a full integer instead of things like “2.999999”. You could do 0.5 + INT on calculators that don’t have an equivalent function.)
Steps 027-030 scale the result to the current least significant digit position. The first time through, I is 0 and 10^0 or 100^0 is 1 so we’re dealing with ones here and the result goes in the ones column. The second time through, I is 1 so we’ll multiply our next least significant digit by 10 or 100 to put it in the display position for the tens digit. For bases of 10 or less, we use 10 and get things like “1011” or “377” or “789”. For bases over 10, we use 100 and get things like “11515” (base 16, or more) or even “10234” (base 36 perhaps). You’ll know whether you’re using a single digit or two digit display base because you keyed in the base.
Once we have a digit in the correct display position, step 031 adds it to our result so far.
Next step 032 adds 1 to our I value. The instruction does include a “and skip if zero” aspect but that won’t happen as we’d need to add 1 until we get to 1 EEX 100 and we don’t have the precision (only 10-12 digits of mantissa) to do that.
Step 033 and 034 get our value/base back and then see how many whole “base”s we had. (eg 9/4= 2.25, = 2×4 + 0.25×4, = 2 fours + 1 ones. We’re getting the 2 here).
Step 035 and 036 is the part where we repeat the process until there is nothing left to convert.
Step 037 and 038 is simply: get the result and stop.
C – Base b to Base 10
For the “C” program (b->10), it looks pretty similar:
039: 31 25 13 : f LBL C 040: 00 : 0 041: 35 33 : STO I 042: 33 00 : STO 0 043: 35 53 : h Rv 044: 31 25 02 : f LBL 2 045: 34 12 : RCL B 046: 81 : / 047: 41 : ENTER 048: 32 83 : g FRAC 049: 34 12 : RCL B 050: 71 : x 051: 34 11 : RCL A 052: 35 34 : RCL I 053: 35 63 : h y^x 054: 71 : x 055: 31 24 : f RND 056: 33 61 00 : STO + 0 057: 35 53 : h Rv 058: 31 83 : f INT 059: 31 34 : f ISZ 060: 31 81 : f x>0 061: 22 02 : GTO 2 062: 34 00 : RCL 0 063: 35 22 : h RTN
I’ll leave you to deconstruct this one. It isn’t that different to the last one.
There’s a copy of the hp67u program in gss001-base-conversion.txt. You should be able to paste that directly into the calculator (Menu / Program).
I should add that you are free to use the program as you wish, personally or commercially and it need not be attributed.
This is part of the HP-67 topic.