Date: Fri, 18 Jan 1991 12:42 CST
Subject: Re: On Unit Objects
Organization: State University of New York @ Buffalo
Lines: 123

In article <54397@eerie.acsu.Buffalo.EDU> cloos@acsu.buffalo.edu (James H. Cloos
   ) writes:
>Hello all.  Hope you had a good holiday season.
>
>(Hmmm, after this I think that the linked array will be the only
>object type whose format is unknown (to the net at large).)
>
>Before I proceed, thanks to Jan & Derek for compiling their internals
>lists, 'frechett@boulder' for posting Derek's to c.s.h, and Jake for
>combining it with Jan's list.  Without Derek's list in specific, I
>would not have figured this out as quickly.
>
>Anyway, it turns out that Unit objects are stored just like lists,
>programs, and algebraics (aka Symbolics).  The format looks like this:
>UNIT real unit1 _ ;
>(where 'unit1' would be a string) for a simple un-prefixed unit, such
>as 2_m.  The '_' though, is just an empty list, but a specific empty
>list.
>
>The prefixes are implemented by combining a CHARACTER with the string
>representing the main unit.
>
>(This room is closing shortly, so I'll be blunt below.  Questions are
>gladly answered ;)
>
>The five list's addresses      What they do
>------------                   ------------
>10b72                          ^ aka power
>10b5e                          * aka mult
>10b68                          / aka divide
>10b86                          _ aka combine real to units
>10b7c                          combine character prefix to unit string
>
>
>I have to go now, so I'll post a followup tomorrow with some more
>info, but this should whet your appatite 'till then.  ;)

Well, a little later than I expected, but I'mm baaaaaaaaack.

Before I forget it, the list of base units is at #FA53h.

So, let me show how the above looks in an actual unit object:
Lets look first at 1_Pa and then UBASE(1_Pa) which is 1_kg/(m*s^2):
1_Pa CMP\-> \->LIST looks like { 1 "Pa" { } } on the stack.
1_Pa \->HX looks like "ADA209C2A2C2A2090000051668B01B2130".
Let's break that up a bit:

ADA20   Unit header
 9C2A2  %1 aka real_1
 C2A20  String header
  90000 String is 9 nybbles long, including these 5
  05 16 Characters #50h and #61h, ie P & a make up the string
 68B01  This is the empty list, above we see it means '_'
B2130   ; aka SEMI aka END : Marks end of Unit,List,Symbolic,Program

IF we then ubase this, we get 1_kg/(m*s^2).  Because we used UBASE,
rather than entering it with the unit menus or the command line, it
will reference the elements of the list at #FA53 that I mentioned
above.  (This list contains:
        { 1_kg 1_m 1_A 1_s 1_K 1_cd 1_mol 1_? }
1_kg/(m*s^2) CMP\-> \->LIST will look like the following no matter how
you enter it:
        { 1 Character "g" { } "m" "s" 2 { } { } { } { } }
However, when you look at it with \->HX, you do get a difference.  If
UBASE is used, you get:
"ADA209C2A226AF096AF0C7B01E8AF0ECAF0ED2A227B01E5B0186B0168B01B2130"
or:

ADA20   Unit header
 9C2A2  %1
 26AF0  Char_k from the BASE list
 96AF0  Chs_"g" from the BASE list
 C7B01  Combine Char prefix to unit String
 E8AF0  Chs_"m" from the BASE list
 ECAF0  Chs_"s" from the BASE list
 ED2A2  %2
 27B01  ^ for units (really empty list)
 E5B01  * for units (really empty list)
 86B01  / for units (really empty list)
 68B01  _ for units (really empty list)
B2130   ;

If this were entered directly, rather than using UBASE, the character
and the 3 strings would be directly in the object.  This is why if you
enter a unit object using either the menus or the command line, using
only base units, DUP it, UBASE the copy, and try SAME, you get 0.
(If you are curious, the char_k looks like "FB920B6" in place of the
26AF0, "g" looks like C2A207000076 in place of 96AF), "m" to
C2A2070000D6 in place of E8AF0, and "s" to C2A207000037 in place of
ECAF0.

So that you too can enjoy digging into these, I've included below 2
ASCified programs.  The first, CMP\->, stands for CoMPosite OUT, and
will break up a list, unit, symbolic, or program.  The actual syseval
that does this is #1C973; the rest of the code just makes sure that
you give it a unit, program, list or symbolic. \->UNT will take a
broken up unit and put it back together.  Just like \->LIST, \->PRG,
and \->ALG.  The routines are basicly the same, but the syseval for
\->UNT is #5481.  I must warn you, though:  Trying to put together an
improper unit object has resulted in a mem lost for me each time.
(Luckily I had a backup in my ram card, which was R/O at the time just
in case ;-)

DIR
 CMP\->.ASC
  "D9D20ECE8112040379C1F3040379C194040379C1B7040379C1B21303471"

 \->UNT.ASC
  "D9D2043C8118450B21302A8A"
END


I hope this proves to be useful.

-JimC
--
James H. Cloos, Jr.             Phone:  +1 716 673-1250
cloos@ACSU.Buffalo.EDU          Snail:  PersonalZipCode:  14048-0772, USA
cloos@ub.UUCP                   Quote:  <>

-----
Here's hoping the Air-to-Ground combat finishes everything, and the
ground forces do not need to become directly involved; and that no
more allied jets go down!

14 Feb 91 00:46
James H. Cloos: >More units

In article <10800@jarthur.Claremont.EDU> sburke@jarthur.Claremont.EDU (Scott Bur
ke) writes:
>Hi.
>
>I must have missed the earlier unit posting, so I must briefly rehash a small
>units problem/question/curiosity:
>
># FA53h SYSEVAL 2 GET gives 1_m, on which BYTES returns #     0d  2.5
>1_m UBASE             gives 1_m, on which BYTES returns # 59779d 12.5
>1_m                   gives 1_m, on which BYTES returns # 54012d 16
>
>This is interesting.  Please (;-), all I want to do is check if a quantity
>that I UBASE (which may or may not be really ugly) is in fact equal to 1_m,
>because I want to know _what_ units the quantity had.

This piqued my curiosity.

The first 1_m above comes out as @FA84 on the stack.  Ie., when you do the
#FA53h SYSEVAL, you get @FA53h on the stack, 2 GETing from there puts the
address of the second element, rather than that element, on the stack.
BYTES sees a ROM object & returns #0 2.5.  In the second case, you get a
UNIT OBJECT on the stack that would look like UNIT %1 String_m u_ ;
where UNIT ==> data.a x'2ada; %1 ==> data.a x'2a2c9; String_m ==> 
data.a x'fa8e; u_ ==> data.a x'10b86; and `;' ==> data.a x'312b (to use
star code for each).  Notice that the string points to a ROM address rather
than being of the form $ "m" (data.a x'2a2c data.a x'7 ascii `m').

I would point out that in a program, the first possibility can be ignored;
it will not happen in ordinary unit manipulations.  (Really, how many
people use #FA53h SYSEVAL 2 GET to enter 1_m on the stack?)

Lastly, here are the addresses of the UBASED units for the 8 base units:
1_kg    #FA58
1_m     #FA84
1_A     #FAA4
1_s     #FAC4
1_K     #FAE4
1_cd    #FB04
1_mol   #FB26
1_?     #FB4A

These are for version A, but are most likely the same for B thru E as well.

(I got these by doing #FA53 SYSEVAL LIST\-> \-> n \<< 1 n START n ROLL
\->HX S\->B NEXT \>>.)  (\->HX is Rick's HEX\-> and S\->B looks like: 
\<< DUP TYPE 2 IF == THEN DUP SIZE 5 + R\->B B\->S 1 5 SUB SWAP + "E4A20"
SWAP + HX\-> ELSE 514 DOERR END \>>
and B\->S looks like:
\<< DUP TYPE 10 OF == THEN \->HX 11 OVER SIZE SUB ELSE 514 DOERR END \>>
and HX\-> is Rick's \->HEX.  (Think of HX format as being just like ASC
format, but w/o the \n's or the crc, and HEX as being the normal format.))

Enjoy!!!

-JimC
--
James H. Cloos, Jr.             Phone:  +1 716 673-1250
cloos@ACSU.Buffalo.EDU          Snail:  PersonalZipCode:  14048-0772, USA
cloos@ub.UUCP                   Quote:  <>
