|
|||||||
Base ConversionsUsers 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) |
|||||||
| |||||||