edp@jareth.enet.dec.com (Eric Postpischil (Always mount a scratch monkey.)) (02/11/91)
Here's a program that implements the function of UBASE for any set of desired base units. This can be used to convert a unit expression to base cgs or English units, or for weirder purposes. To use, create a list of eight units. Each item in the list can be just the name of a unit, e.g. { cm g s . . . }, or items can be more complicated unit expressions, such as 1_m*s. The units of the eight items must be linearly independent -- there must not be any way to multiply and divide any selection of up to seven items so that they equal an eighth. This is equivalent to saying there must be a way to convert each HP-48 base unit, including "mol" and "?", to one of the units in the list you supply. Put that list in stack level one and execute SETU (Set Units). It will create a variable Upar which is that list plus a new element -- an 8-by-8 array. To convert a unit expression to your basis, put the unit expression in level 1 and execute CONVERTB (Convert to Basis). Some notes: Units will appear in the resulting expression in the order they appear in your list (except that if the list contains compound unit expressions, elements of them may be combined -- e.g., if you have m*s and m*g, you may get m^2*... in the result). Be careful when converting temperatures. Fractional exponents are not supported. Fractional exponents in your input will be rounded to integers. You might be able to get away with some fractional outputs by removing the 0 RND in CONVERTB -- but be aware that the array calculations may give results like .999999..., and removing the 0 RND will leave these in the output. If you expect 1/2 powers in your output, then 1 RND would be good, and 9 RND or something might be suitable in other cases. If you will not be using "mol" or "?", the program could be altered to work on fewer than all 8 base units, with some savings in space and possibly time. You can recall Upar, edit it, and pass it to SETU to change the base units. SETU will ignore the ninth element, the array. -- edp (Eric Postpischil) "Always mount a scratch monkey." edp@jareth.enet.dec.com My routines use Bill Wickes' DIMS, so here it is again. Download it, convert it with ASC->, and store it in a variable called 'DIMS'. %%HP: T(3)A(D)F(.); "D9D20D29512BF81B7040D9D2044EF0A211693045FC436ADB46AAC35F30403C37 088130E4A2070000FF40D35D53453392020000000000072102C230178A2CB916 D9D20339202000000000006520189A2B21303223019D35433706B436AAC35442 30B2130B21303587" Here is the directory 'BASIS', checksum #65FA. Interestingly, 'BASIS' BYTES gives 268.5 bytes, 'BASIS' RCL BYTES gives 269 bytes. %%HP: T(3)A(R)F(.); DIR CONVERTB \<< DUP DIMS { 1 8 } \->ARRY Upar 9 GET * 0 RND \-> e \<< 1 1 8 FOR i Upar i GET e i GET ^ _ NEXT CONVERT \>> \>> SETU \<< \-> list \<< 1 8 FOR i 1 list i GET _ DIMS NEXT { 8 8 } \->ARRY INV list 1 8 SUB SWAP + 'Upar' STO \>> \>> END