[comp.sys.handhelds] HP48 compact arrays

seroussi@hplabsb.HP.COM (Gadiel Seroussi) (02/08/91)

The binary directory (in ASC-> format) appended at the end of this message
uses HP48 linked arrays to implement "compact arrays" of positive integers. 
These arrays allow you to store large tables of positive binary integers using 
significantly less storage than would be required with either real arrays or 
lists of binaries, with an access time comparable to that of real arrays (much 
faster than lists of binaries).
A compact array shows on the stack as "Linked Array", and cannot be edited
directly (conversion routines are provided).
The internal structure of a compact array is as follows:
<02a0a> - header (5 nib)
<size>  - size of object excluding header (5 nib)
<isize> - size of array elements, in nibbles (5 nib)
<n>     - number of elements (5 nib)
<element 1> <element 2> ..... <element n>  (<isize> nibbles each).

Other headers could have been choosen but "linked array" was unused enough to
justify the choice (and choices like "code" or "string" would be confusing).

The following variables are included:

IGETB: retrieve an element of the array, as a binary number.

	2: A (compact array)
	1: k (Real)          ----> 1: A(k)  (binary)

IGET: retrieve an element of the array, as a real number.

	2: A (compact array)
	1: k (Real)          ----> 1: A(k)  (Real).

If k <= 0, the number of elements of the array is returned. Subscript range
is checked.

IPUT: store a value in the array.

	3: A (compact array)
	2: k (Real)
	1: x (Real or binary)  ----> 1: A (compact array, with A(k)=x).

Subscript range is checked, k <= 0 is not allowed. The value x is truncated
to the size of the array elements.

ICON: generate a compact array with constant elements.

	3: n (Real)
	2: isize (Real)
	1: c (Real or binary)  ----> 1: A (compact array).

A has n elements, isize nibbles each, all set to the value c. While it is 
legal to set isize > 16, the access routines will only handle up to 16 nibble 
values.

ISIZE: find out the value of <isize>.

	1: A (compact array)   ----> 1: isize (Real)

ITOA: Convert compact array to real array.

	1: A (compact array)   ----> 1: RA (Array of Real).

ITOB: Convert compact array to list of binaries.

	1: A (compact array)   ----> 1: BL (List of Binary).

ATOI: Convert real array to compact array.

	2: RA (Array of Real)  
	1: isize (real)        ----> 1: A (compact array)

BTOI: Convert list of binaries to compact array.

	2: BL (List of Binary)
	1: isize (real)        ----> 1: A (compact array)

For both ATOI and BTOI, if isize == 0, the least number of nibbles will be 
used that can accomodate the largest value in RA or BL (resp.).

BMAX: Find the largest value in a list of binaries (aux. function).

p.small: an example of a compact array. A list of the first 1000 prime numbers.
	It takes 2010 bytes of storage, compared to 8012.5 bytes for a real
	array, or around 7000 bytes for a "well packed" list of binaries
	(which ITOB will NOT produce).

Other remarks:
1. The conversion routines are written in user language. Since I consider
   them "one-time" events, no special effort was made to make them faster.
2. All access routines are affected by the current setting of the binary
   word size (set word size >= isize for things to work properly).

This package was developed for a Version D ROM. It may or may not work on
yours. It may or may not destroy your data and/or your calculator.
Use it at your own risk. No warranties of any kind.

Enjoy,

Gadiel Seroussi
HP Labs (but no relation to Corvallis)

-----------------------------------------------------------------------------
Downloadable directory. Download in ASCII mode, use ASC-> to create
a directory object, save it under whatever name you like.

%%HP: T(3)A(R)F(.);
"69A20FF7F8910000007007E237D616C6C670A0A20FAF00400008E30020003000
50007000B000D000110031007100D100F10052009200B200F2005300B300D300
340074009400F40035009500160056007600B600D6001700F70038009800B800
59007900D9003A007A00DA003B005B00FB001C005C007C003D00FD003E005E00
9E00FE001F00BF0010107010D010F01051109110B1105210331073109310D310
B4101510B510D51016107610F6105710B710F7105810D810191099103A105A10
FA101B107B10BB101C109C10DC10FC103D10FD107E10BE103F107F10DF109020
B020D1203220D22033209320B3201420B420152075209520F52056209620B620
7720182038207820D820392059201A205A20BA203B20DB205C20FC207D20DD20
3E207E20FE205F209F20103050303130D1309230B23053307330B330D3307430
55309530B530F530D630173037307730B830F83079301A309A30DA303B309B30
7C30BC301D307D30FD305E301F305F30BF30DF3070409040F0409140B1405240
7240D240F340344054409440F4405540D54036409640F7401840B8403940D940
3A409A401B40DB401C407C40DC40FC405D401E40BE40DF40FF4030509050B050
115051507150B15072509250F25015507550D550565077501850F85039505950
9950F9507A50BA50DA503B50FB509C50BC50FC501D505D50BD507E503F50BF50
7060D06011607160F1603260B260F260D360146074609460D46035605560B560
56609760F76038605860D9601A603A60DA609B60BB605C60DC603D609D60FD60
1F607F60BF60DF6090703170F170727073705470B470F4701570557075701670
D67037709770B870D870D970F9705B70BB703C709C70DC70FC703D70BD701E70
BE70DE707F705080F080518012803280728092803380F3801480158035809580
D580F580968017803880B980F9805A80DA80DB80FB803C80BC80BD80DD801E80
9E80FE805F809F8050907090D19032905290B290F290539034909490D490F490
55909590F590B6901790779058909890F890B9903A909A90DA907C909D903E90
BE90FE905F907F90DF9031A0F1A012A013A093A0D3A094A075A016A036A076A0
F6A057A0B7A0F7A018A058A0B8A039A079A099A0F9A09AA0BAA05BA0DBA01CA0
FCA09DA05EA07EA0DEA01FA03FA030B011B051B0B1B032B092B0D2B0F3B074B0
15B075B0D5B056B0F6B0B7B098B0D8B039B099B0B9B07BB09BB03CB0BCB0FCB0
DDB01EB09EB05FB0BFB070C0B0C011C052C0F2C013C014C0B5C0F5C016C0D6C0
37C077C038C098C019C059C0D9C03BC05BC09BC0BBC07CC03EC05EC0BEC01FC0
7FC0BFC010D030D0F0D031D0F1D012D0B2D0D2D0D3D0F3D0F4D055D096D097D0
18D058D078D0B8D0D8D03AD0BAD07BD0DBD07CD09CD0DCD03DD05DD0BDD05ED0
7ED03FD0DFD0FFD090E071E0D1E012E072E0F2E053E0B3E0B4E075E095E0D5E0
B6E017E057E0D7E078E0F8E059E0B9E01BE07BE09BE03CE01DE05DE0BDE0DEE0
FEE09FE070F0B0F0D0F071F052F092F013F034F074F0D4F0F4F035F095F0B5F0
76F0B6F0F7F059F01AF03AF07AF0DAF03BF05BF0BBF01DF03DF09DF09EF0FEF0
BFF0DFF03001F001F10112015201B2019301D301F3011501960137019701B701
5801780119013901D9013A015A01FA011B01BB011C019C017E011F013F01DF01
5011B01151117211D2119311541174119511F51136119611F61118113811D811
B9111A115A117A11BA113C115C111D117D117E11FE115F11BF11D021D121F121
32219221B22113217321142174213521F521172137219721D721F8217921FA21
3B215B219B21FB211C21DC211D21FD21DF217031D03191317231D23173313431
54319431F4317531D53176319631D631B73118317831B83119313931D931F931
FA31BB313C315D319D31FD31BE31DE313F319F31FF31B1411241F2413341B341
5441D4419541B641F64117415741D8419941F9411A411B417B41DB41BC415D41
3E417E415051B05111517151F15152519251B2517351D351145134519451F551
56517651B651D751F7513851F85119517951B9515B51BB511C515C51DC517D51
7F5170619061F061316151619161B161526133619361D3615461F46155619661
D661F661576139617961F9619A61FA615B61DB613C61FC613D619D61BD611E61
5E61BE61DE617F619F619071F0713271727133711471D57136717771B771D871
5971B971F9715A713B719B71FB719C71BC715D711E719E713F715F71FF717081
3181D18153817381B38134819481D4815581768117817781D781F7815881F881
B981D9817A81DA813B819B811C817C811D817D819D81FD815E81BE815F81DF81
5191B19113913391549194911591B591979118913991799199913A919A91BA91
1B915B917C91FC91BD91DE91DF9130A150A111A171A112A132A1D2A1F2A153A1
F3A1D4A115A196A1B6A1B7A1D7A178A198A139A17AA1BAA1DAA11BA19BA19CA1
FCA15DA17DA13EA13FA1BFA1FFA150B132B152B1F2B113B173B1B3B114B174B1
F4B155B195B156B1B6B137B1F7B138B119B1D9B17AB1FBB15CB11DB17DB19DB1
FEB17FB190C131C191C172C1B2C1D2C133C1D3C154C1B4C1F4C155C137C118C1
B8C1D8C199C13AC15AC15BC17BC19CC11EC13FC19FC190D1B1D112D132D153D1
93D1F3D114D1B4D135D1D5D136D196D117D157D1B7D1D7D178D198D159D199D1
F9D15AD17AD13BD17BD15CD17DD1BDD11ED15FD19FD110E170E1B0E131E171E1
52E1B2E1F2E1D3E194E1D4E1F4E1D6E117E198E1F8E159E11AE1DAE1BBE11CE1
5CE17CE1BCE1DDE13EE1FEE16CF004024D4148540D9D20E1632B7FC1E4A20510
0000000000000000001C432D6E2010E6D6E2030D61687E16329C2A2D6E2010E6
301323CE2278BF1D6E2030D61687D5CE1AFE22D9D2045632D6E2030D61687976
32DCC02B21305BF228DBF15DF22C4232D6E2030D61687EF53293632B2130FD00
0402445F49440D9D20E16321C432D6E201016D6E2010C6E16323CE22D6E20101
668BC1D13A2D9AE1AFE22D9D20D6E201016E4A20510002020000000000000933
A1B21305DF22EF5C13392010000000000004605C5C1D6E2010168B9C178BF13C
E22D6E2010C6F88E1AFE22D9D20D6E20101684E204024D41485BB69178BF1F88
E176BA1F49B1339201000000000000610F49B150FA19C2A276BA1D6BB1B21305
BF22D6E2010C65DF22E4A2051000000000000000000084E20409434F4E49C2A2
E0CF10A132D6E201096D6E201096D6E20101692CF16C7D184E204094055545C4
232DBBF15C5C1EF53293632B2130BD100401445F49440D9D20E16321C432D6E2
01016D6E2010C6E16323CE22D6E2010168B9C1B7FC19C2A2D9AE1D6E20101668
BC13F2A2D9AE1908E1AFE22D9D20D6E201016E4A205100020200000000000009
33A1B21305DF22EF5C1DBBF178BF13392010000000000004605C5C13CE22D6E2
010C6F88E1AFE22D9D20D6E201016E9FB178BF1F88E176BA1F49B13392010000
00000000610F49B150FA19C2A276BA1D6BB1B21305BF22D6E2010C65DF22E4A2
051000000000000000000084E20409434F4E49C2A2E0CF10A132D6E201096D6E
201096D6E20101692CF16C7D184E204094055545C4232DBBF15C5C1EF5329363
2B21305E100409445F42440D9D20E163278BF14B2A284E2040947454451C432D
6E2020C616D6E2010E6E16329C2A2D6E2010E60A132D6E201096D6E2020C616D
6E20109684E20509474544524C4232D6E2010E6387C1EF53293632B21300B000
409445F41440D9D20E163278BF14B2A284E2040947454451C432D6E2020C616D
6E2010E6E16329C2A2D6E2010E60A132D6E201096D6E2020C616D6E20109684E
204094745445C423247A20D6E2010E6B2130900D1EF53293632B21308B000509
43594A55450D9D20E163278BF19D1A1DBBF18DBF1ED2A2EEDA13392010000000
0000002090DA1DBBF14B2A284E20409474544550FA193632B213087000409434
F4E440D9D20E1632D9D200FE811192011100B969111920B1100D9D20B2130B21
303F2A20DCF13CE2278BF1F88E1AFE22D9D208DBF19C2A2B21305DF227F4912A
BF19B191CCD20CC0008FD5F301001098F146601028FB9760119818F2E109818F
248FEB9301321302034A0A2014416411914416411814416411A1441008F2D760
8FD8F35118818F29134146D5CE80D016911AD78AB411501136C9134CF6CEF8F2
D7601101C4141CF142164808C93632B213096100409405554540D9D20E1632D9
D200FE8111920B1F50D9D20B21301192011F50B9691B2130E0CF1CB2A1E0CF1A
EC81E0CF1CCD20FC0008FD8F351018F2D7608F146601001438FB976013016414
2164146818F8EEA103CE80D0E6169110AF8AF0B74100CD4E4D08AA61808A040C
0C5819F26AEF11B8B6B2136C213411115018F2D760208F73560142164808CD21
088F2D7601C9818FB18FB976069CF69816D9D20DBBF1FBD81DBBF1E4A2080000
302933A1B213093632B2130F6100409474544540D9D20E163284E20509474544
524BB69193632B21306300050947454452450D9D20E1632FDE81119201F500D9
D20AEC81CCD206D0008F14660100143174E78FB9760130164142164146818F8E
EA101CE80D0E6164110D8AF0B741001428A993164CDD08AA61808A040C0C5819
F26AEF1198B673136C2134AF015211028F2D760208F735608FB97602F1128FD6
950D21088F2D7601C9818FB18FB97606DBFDBBF169816D9D208DBF1FBD81E4A2
080000302933A1B2130B213093632B2130C713"

seroussi@hplabsb.HP.COM (Gadiel Seroussi) (02/09/91)

In article <2918@charon.cwi.nl>, jurjen@cwi.nl (Jurjen NE Bos) writes:
> How do we know for sure that the HP48 ROM does not make any assumptions about
> the comtents of a Linked Array?  The name suggests that the contents may ahve
> a structure that contains addresses of other objects............

We don't know for sure. The question is, who looks at the linked array? These 
programs do not use any built-in function or ROM object to access the 
linked array. The only access is thru the ML code, which actually ignores the 
object header (the latter is only looked at during argument checking). 
I agree that there is a remote possibility that the garbage collector could 
object, but that seems unlikely, and after very extensive use of these objects, 
I have yet to encounter that problem.

> Until that moment, I don't consider it a safe idea to use Linked Arrays as
> objects in a program.

That is, of course, very understandable (remember all disclaimers), and  
a matter of personal preference. I think that, among all the "officially unsafe"
things we do with our calculators, this one is probably on the mild side.

Gadiel

akcs.gadiel@hpcvbbs.UUCP (Gadiel Seroussi) (02/13/91)

Derek Nickel asks why not use Array of System Binary for compact arrays.
There are a few problems with that: I wanted to represent binary 
numbers of any length with the minimum possible number of nibbles
(up to 16 nibbles). Even if we ignore 5-nibble boundaries, we would
still need to have a multiple of 5 nibbles. But, worse, as you point
out in your notes, the system thinks that any array that is not of 
Reals is a Complex Array, and will let you edit it on the Matrix
Writer, which, in our case, could lead to catastrophic consequences
(try it on an Array of System Binary with just one element. BACK-UP
before you do this!!!).
What I wanted was a data type that could not be easily manipulated except
for the provided functions. That more or less rules out all other 
types, except Code, but I don't need to tell you why using Code would
be a terrible idea. So, so far I have not seen any convincing argument
against using Linked Arrays. By the way, one assertion (at least) in 
a previous posting of mine was incorrect: I do use a built-in object
(NEWOB) on linked arrays in the IPUT function, and nothing bad happens.
Gadiel

grue@batserver.cs.uq.oz.au (Frobozz) (02/13/91)

In <27b83c55:1997.3comp.sys.handhelds;1@hpcvbbs.UUCP> akcs.gadiel@hpcvbbs.UUCP (Gadiel Seroussi) writes:

>What I wanted was a data type that could not be easily manipulated except
>for the provided functions. That more or less rules out all other 
>types, except Code, but I don't need to tell you why using Code would
>be a terrible idea. So, so far I have not seen any convincing argument
>against using Linked Arrays. By the way, one assertion (at least) in 
>a previous posting of mine was incorrect: I do use a built-in object
>(NEWOB) on linked arrays in the IPUT function, and nothing bad happens.


Why not use a binary integer (or even a string, they are stored identically)?
The HP can handle extended length binarys (have a look at the alarm stuff in
the nameless directory), there would be no problems calling internal routines
on them.  Of course, the user might ba able to abuse them a little.  This
method does have the advantage that you are using a data type whose behaviour
is relatively well known (it is unlikely to surprise you in mysterious ways).
Linked arrays are currently a big unknown (I've seen nothing about them
anyway), NEWOB could cause all kinds of problems (since it can trigger
garbage collections which will know something about real linked arrays).


This isn't really a convincing argument against using linked arrays, it is
more an expression of an alternative option.  (I use strings for my machine
code accessable data structures when a built-in type is not adequate.  My
reversi program does this and it is the only machine code I've posted that
uses this 'trick' --- I think).






							Pauli
seeya

Paul Dale               | Internet/CSnet:            grue@batserver.cs.uq.oz.au
Dept of Computer Science| Bitnet:       grue%batserver.cs.uq.oz.au@uunet.uu.net
Uni of Qld              | JANET:           grue%batserver.cs.uq.oz.au@uk.ac.ukc
Australia, 4072         | EAN:                          grue@batserver.cs.uq.oz
                        | UUCP:           uunet!munnari!batserver.cs.uq.oz!grue
f4e6g4Qh4++             | JUNET:                     grue@batserver.cs.uq.oz.au
--

jmorriso@hershey.ee.ubc.ca (John Paul Morrison) (02/14/91)

If people are worried about users inadvertently accessing data stored in
a code, string, or binary object, any object can be hidden inside a library data
object. Library data objects can't be edited, or accidentally modified. They
show up as "Library Data" on the stack, so that is less confusing to a user,
than "Array of String".

If you unthread the PTpar variable, you will see it only has a string inside.
The MHpar variable contains a list which has a GROB, a string, and some Sytem
Binaries inside.