In order for this site to work correctly, and for us to improve the site, we need to store a small file (called a cookie) on your computer.
By continuing to use this website, you agree to our cookies and privacy policy.
  
Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel

Base Conversions

Users of other systems coming to AREV for the first time cannot help but notice that as a consequence of the lack of "typing" data, is that all data is stored as ASCII strings with no specialised storage for integers or real numbers. This is not a particularly efficient way of coping with integers, one byte could be used to represent a number between 0 and 255 rather than just 0 and 9 as at present.

Normally this restriction is not a limitation, but in the case of relational indexes it can severely limit our system. As a rough rule of thumb, assuming a five digit key, only 8-10,000 record keys can be stored in a relational index. In addition, one BTREE node (being limited in size to around 1K) can only store 150-200 such keys, meaning that every 150-200 keys returned from a BTREE.EXTRACT operation requires an additional disk i/o.

It would therefore be a good idea were an alternative base to be used in place of base 10 for integer keys. If a higher base, such as base 210, were used, two bytes could contain up to 44099 rather than 99. This sort of compaction more than doubles the amount of records possible to maintain in a relational index, and does the same for BTREE nodes.

The choice of base within AREV is limited. We need to express the number by storing ASCII characters. If we used Base 256,


0001            CHAR(0)             =    0
0002            CHAR(1)             =    1
0003            CHAR(254)           =    254
0004            CHAR(1) : CHAR(1)   =    257 (1 * 256 + 1) etc.

The system, however uses characters above 246 as delimiters, so characters above 246 could not be used as they would be treated as delimiters. It might therefore seem reasonable to use Base 246 so these problems are not encountered. However the use of Base 246 is again precluded, because as has been shown in REVMEDIA passim, low ASCII characters can create problems with keys. A base starting at CHAR(33) (so as to avoid spaces in keys) and finishing below CHAR(247) is therefore desirable - for personal reasons, the author chooses to use Base 210.

The best way to implement the use of another Base within AREV is as a User Defined Conversion. On ICONV the routine must take an ASCII integer and process it to create the data in the alternative base. On OCONV the routine must take the alternative base data and convert it back to a Base 10 integer.

The code presented below achieves this functionality. If defaults to Base 210 but any base may be used by using the option branch label on the ICONV/OCONV call. The routine must be entered, compiled and and catalogued. Then to convert 2500 to Base 210 one would use INTERN = ICONV(2500,"[BASE]"). To convert to Base 150 one would use INTERN = ICONV(2500,"[BASE,150]". TO OCONV reverse the exercise, eg EXTERN = OCONV(INTERN,"[BASE]") and EXTERN = OCONV(INTERN,"[BASE,150]") respectively.

Note that this form of Base conversion is not what a mathematician would term a Base conversion but it achieves our required objectives.


0001    SUBROUTINE BASE (TYPE,PASSED,BASE,RET.VAL)
0002    *
0003    *         Author    AMcA
0004    *         Date July 1990
0005    *         Purpose   Provide a base conversion conversion
0006    *         Notes     Note that 33 is added on ICONV subtracted on OCONV to
0007    *                   ensure that all stored characters are > " " thus zero
0008    *                   will always be stored as ! ( 0 + 33) = CHAR(33)
0009    *
0010      IF BASE = "" THEN BASE = 210 ; * Default
0011      BEGIN CASE
0012         CASE TYPE  = "ICONV"
0013            GOSUB ICONV
0014         CASE TYPE = "OCONV"
0015            GOSUB OCONV
0016      END CASE
0017    RETURN
0018  
0019    ICONV:
0020      RETURNED = ""
0021      SAVE_PASSED = PASSED
0022      LOOP
0023         PASSED = INT(PASSED/BASE)
0024      WHILE PASSED DO
0025         IF PASSED > BASE THEN
0026            *
0027            * Just add in remainder and continue
0028            *
0029            RET.VAL=CHAR(MOD(PASSED,BASE)+33): RET.VAL
0030         END ELSE
0031            RET.VAL = CHAR(PASSED+33) : RET.VAL
0032         END
0033      REPEAT
0034      *
0035      * Finally add on remainder
0036      *
0037      RET.VAL := CHAR(MOD(SAVE_PASSED,BASE) +33)
0038    RETURN
0039  
0040    OCONV:
0041      RET.VAL = ""
0042      LENGTH = LEN(PASSED)
0043      FOR X = 1 TP LENGTH
0044         VALUE = SEQ(PASSED[X,1])-33
0045         *
0046         * If the variable is three characters long the first byte must be
0047         * multiplied by the base raised to the power 2 (length -1), the
0048         * second byte must be multiplied by the base raised to the power 1
0049         * (length -2) and the final byte must be multiplied by 1 (that is the
0050         * same as the base raised to the power 0 (length -3)
0051         *
0052         VALUE = VALUE * (BASE^(LENGTH- X))
0053      NEXT
0054    RETURN

(Volume 2, Issue 4, Pages 7,8)
Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel