After I developed my right-to-left conversion program, I thought I’d better re-check the solutions presented here before I asserted that they were all left-to-right. (I admit to not having studied them all in detail on first reading.) Your program looked similar to others that did it left-to-right, but then I noticed the MOD instruction and deduced you were doing it right-to-left.
Regarding your use of MOD, I decided to try that instead of my method using FP to strip off one digit right of the decimal and then multiplying by 10. Doing so required me to use a (local) storage register, but I was also able to make it one step shorter, down to 26:
001 ENTER duplicate entered value
002 EXPT extract exponent
003 +/- change sign of exponent
004 #011 enter 11
005 + add 11 to exponent
006 #008 enter 8
007 x<>Y swap
008 y^x calculate multiple of 8 for least significant digit
009 x<>Y swap
010 MANT extract mantissa of N
011 SDL 11 multiply by 1E11
012 LocR 001 create one local register to accumulate sum
013 RCL X get stack in right order
014 #010 enter 10
015 RMDR extract units digit using RMDR
016 STO-Y subtract from original to remove units digit
017 RCL/ Z divide by current power of 8
018 STO+ .00 add to current sum
019 CL x Clear X, disable stack lift
020 #008 enter 8
021 STO/ Z divide into current power of 8 for next power
022 Rdown roll down
023 SDR 01 divide by 10
024 x=/=0? check if done
025 BACK 012 loop back until done
026 RCL .00 done, recall converted value
Of course if I use a local storage register in my original version, I also save a step. The local register starts at zero, and so eliminates the need to enter a zero, which then saves a stack manipulation step later:
001 ENTER duplicate entered value
002 EXPT extract exponent
003 +/- change sign of exponent
004 #011 enter 11
005 + add 11 to exponent
006 #008 enter 8
007 x<>Y swap
008 y^x calculate multiple of 8 for least significant digit
009 x<>Y swap
010 MANT extract mantissa of N
011 SDL 10 multiply by 1E10
012 LocR 001 create one local register to accumulate sum
013 RCL X get stack in right order
014 FRAC take fractional part (only one digit)
015 STO-Y subtract from original to get integer part in Y
016 SDL 01 multiply fractional part by 10
017 RCL/ Z divide by current power of 8
018 STO+ .00 add to current sum
019 CL x Clear X, disable stack lift
020 #008 enter 8
021 STO/ Z divide into current power of 8 for next power
022 Rdown roll down
023 SDR 01 divide by 10
024 x=/=0? check if done
025 BACK 012 loop back until done
026 RCL .00 done, recall converted value
Assuming I understand it correctly, I like your method of adding a digit, then dividing by 8 to push the result one octal digit. Eliminates the need to raise 8 to some power and keep a running multiple of 8. I think I’ll see if I can work that into my method to handle all 12 digit inputs.
Improved version, using Pauli's method to convert the mantissa from right to left, then shift that left or right as needed based on the exponent by raising 8 to the appropriate power:
1 LocR 002 create two local registers
2 STO .01 store entered value
3 MANT extract mantissa of N
4 SDL 11 multiply by 1E11
5 RCL X duplicate value
6 #010 enter 10
7 RMDR extract units digit using RMDR (to work for neg)
8 STO-Y subtract from original to remove units digit
9 STO+ .00 add to current sum
10 #008 enter 8
11 STO/ .00 push sum one octal digit right
12 RCL Z Recall previous value less units
13 SDR 01 divide by 10
14 x=/=0? check if done
15 BACK 010 loop back until done
16 x<>Y swap
17 RCL .01 recall original entry
18 EXPT extract exponent
19 INC X add 1 to exponent
20 y^X 8^(EXPT+1)
21 RCLx .00 recall converted mantissa value, multiply by 8^p
Last and maybe least, the following version converts the maintissa rigth to left, then shifts the result left or right as required by repeatedly multiplying by 8 or 1/8. The thought is that repeated multiplication may be more accurate than raising 8 to some power.
11 LocR 002 create two local registers
2 STO .01 store entered value
3 MANT extract mantissa of N
4 SDL 11 multiply by 1E11
5 RCL X duplicate value
6 #010 enter 10
7 RMDR extract units digit using RMDR (to work for neg)
8 STO-Y subtract from original to remove units digit
9 STO+ .00 add to current sum
10 #008 enter 8
11 STO/ .00 push sum one octal digit right
12 RCL Z Recall previous value less units
13 SDR 01 divide by 10
14 x=/=0? check if done
15 BACK 010 loop back until done
16 x<>Y swap
17 RCL .01 recall original entry
18 EXPT extract power of 10
19 x=/= 0? check if exponent is zero
20 SKIP 001 if not zero, skip to SIGN
21 INC X if zero, set equal to 1
22 SIGN get sign of exponent
23 y^X raise 8 to 1 or -1 power to get 8 or .125 multiplier
24 RCL .01 recall original entry
25 EXPT extract power of 10
26 INC X add 1 to exponent
27 ABS take absolute value for loop index
28 x=0? check if loop index equals zero
29 SKIP 005 if so, done, go to end
30 RCL Y recall 8 or .125
31 STOx .00 multiply by 8 or .125 to shift left or right
32 x<>Y swap
33 DEC X decrement index
34 BACK 006 go back for next shift
35 RCL .00 recall answer
edit 1 - changed MOD to RMDR in first program to make it work with negative inputs.
edit 2 - added new version
edit 3 - added final version
Edited: 23 Oct 2013, 8:46 a.m.