[comp.sys.handhelds] HP28s program to convert to/from multiple unit lists

jrl@images1.Waterloo.NCR.COM (john Latala) (04/09/90)

Here's a modification of a program I posted awhile back.  The original
posting consisted of two programs called BR (base representation) and BV
(base value).  With BR you could answer questions like: How long is
12345 seconds? By doing: 12345 <enter> { 365 24 60 60 } <enter> BR
<enter> and it would return: { 0 3 25 45 } (12345 seconds is 3 hours 25
minutes and 45 seconds). 

BV would do the reverse: { 0 3 25 45 } <enter> { 365 24 60 60 } <enter>
BV <enter> would return: 12345. 

This was all working quite well, but you had to remember what numbers to
put into the list of base weights.  { 365 24 60 60 } means that there
are 60 seconds to a minute, 60 minutes to an hour and 24 hours to a day
and finally 365 days to a year. 

With the units capability of the HP28S there had to be a better way. 
After a bit of tinkering I came up with: UL, the unit list program. 

The above example in UL would be: 12345 <enter> { d h min s } <enter> UL
<enter> and it would return { 0 3 25 45 }.  To reverse this calculation
with UL you would do: { 0 3 25 34 } <enter> { d h min s } <enter> UL
<enter> and UL returns 12345. 

UL determines which conversion it's doing by checking the type of the
arguments.  They're either both lists or a number and a list. 

One of the nice things about this is that it works nicely with user
defined units!

Checksums were calculated using the standard HP28 checksum program. 

UL : {BBF3}
<<
  -> a1 a2
  <<
    IF a1 TYPE {} TYPE == THEN
      0 
      a2 DUP SIZE GET
      -> tu
      <<
        1 a1 SIZE
        FOR i
          a1 i GET a2 i GET tu CONVERT DROP +
        NEXT
      >>
    ELSE
      a2 DUP SIZE GET 
      -> bu
      <<
        1 a2 SIZE 1 -
        FOR i
          a1 a2 i GET
          -> tu
          <<
            bu tu CONVERT DROP IP DUP 
            tu bu CONVERT DROP IP a1 SWAP - 'a1' STO
          >>
        NEXT
      >>
      a1 a2 SIZE ->LIST
    END
  >>
>>

One thing that I'm not sure about is the use of the IP instructions in
the above code.  This appears to work provided the units being used are
always related to each other in integral steps.  Things will work with
units {a b c} provided 'a' is an integral number of 'b' and 'b' is an
integral number of 'c'.  In most instances this appears to be true, but
is it a problem?

If it is a problem I can't think of an easy way around it.  Any ideas?

One interesting thing I'm using UL for now is the ability to add unit
lists.  With an ADD program like:

ADD : (17D9)
<<
  -> n1 n2 ul
  <<
    n1 ul UL
    n2 ul UL
    +
    ul UL
  >>
>>

you can add miles/feet/inches.  How long is 12 miles, 1234 feet and 8
inches plus 8 miles, 3456 feet and 1 inch?

    {12 1234 8} <enter> {8 3456 1) <enter> {mi ft in} <enter> UL <enter>

and you get the answer: {20 4690 9) (20 miles, 4690 feet and 9 inches). 
The only messy part that I've come across is how to add a sign to a unit
list.  Any ideas?


john.Latala@Waterloo.NCR.COM