COMP% ===== Compare two values of any type This is an expansion of my original CMP% function which was limited to strings only. Usage: ====== result% = COMP%(X, Y, <cmptype.b><vartype.b)) Where result% is either 1 => X > Y or 0 => X = Y or -1 => X < Y X and Y are the two values to be compared. They are assumed to be of the same type. <cmptype.b> in the most significant byte of the word is the code for the Qdos comparision type 0..3 (see below for details) The <cmptype> is only significant for string comparisions and is otherwise ignored. If ct% = 1 (case agostic string comparison) and vt% = 14 (variable type string) then ct% * 256 + vt% will meet the case: r% = COMP%('abc', 'ABC', 256 + 14) returns r% = 0 r% = COMP%('abc', 'ABC', 14) returns r% = -1 <vartype.b> in the least significant byte of the parameter is a code defining the kind of parameters to be compared (see below). Variable types: =============== sbyte = $00 = 0 signed byte ubyte = $02 = 2 unsigned byte sword = $04 = 4 signed 16 bit word uword = $06 = 6 unsigned 16 bit word slong = $08 = 8 signed 32 bit long word ulong = $0A = 10 unsigned 32 bit long word fltpt = $0C = 12 48 bit float qstrg = $0E = 14 Q-string (len.w + bytes) cstrg = $10 = 16 C-string (zero-terminated) nstrg = $12 = 18 Name string (1 byte length) S*BASIC doesnt normally deal with unsigned integers word or longword, so the unsigned word 64302 has to be entered as -31534 (= 32768 - 64302). Bytes in S*BASIC are always treated as unsiged. COMP% lets you treat them as signed or unsigned. Types 0 to 6 are fetched by S*BASIC as standard word integers, types 8 and 10 as long word integers, type 12 as standard floating point numbers, and type 14 as standard strings. Types 16 and 18 are not supported by COMP%, they must be converted to Q-strings first. You could use CSTR$ and NSTR$, as found at Knoware.no for that, if the strings are stored in memory String comparison: ================== Comparisons may be: Type 0 Made directly on a character by character basis Type 1 Made ignoring the case of the letters Type 2 Made using the value of any embedded numbers Type 3 Both ignoring the case of letters and using the value of embedded numbers. More detail of the order of characters etc, may be found in the various QL Concepts manuals, or in the text accompanying my CMP% keyword at Knoware.no Examples: ========= COMP% doesnt do coersion, ie make one type of variable into the same class as another before comparing them; both variables are assumed to be of the same type. However, S*BASIC's parameter fetching routines do coercion pretty well, so you can make use of this: FOR t = 0 to 14 STEP 2: PRINT COMP%(190, 22, t), This will print -1 followed by six 1s and a final -1. How come? t = 0 = sbyte. Signed byte 190 is the negative number -66, so -66 < 120 t = 14 = qstrg. With normal strings the 1 in 192 is < than the 2 in 22 S*BASIC converts, or tries to, the parameters to integers, longs, floats or strings before the comparison takes place using the type specified. With qstrgs we have one more card to play. If the comparison type includes the value of embedded numbers the caclulation changes: PRINT COMP%(190, 22, 2 * 256 + 14) - prints 1, because 190 > 22. The same for PRINT COMP%(190, 22, 3 * 256 + 14), representing string comparison type 2 and 3, as mentioned above. The following listing is an example of COMP% used to sort arrays of various kinds. RUN in in the standard S*BASIC 3-window console. Press a key after the BEEP and check out the differences. 10 RANDOMISE 12 DIM A%(9), A(9), A$(9, 10) 14 FOR i = 0 TO DIMN(A%) 16 A%(i) = RND(0 TO 255) 18 A(i) = RND(-512 TO 512) 20 IF RND(1) THEN 22 A$(i) = CHR$(RND(65 TO 90)) 24 ELSE 26 A$(i) = CHR$(RND(97 TO 122)) 28 END IF 30 END FOR i 32 : 34 Dis#2 36 BIS A%, 0: rem Unsigned byte 38 BIS A , 4: rem Unsigned word 40 BIS A$, 14: rem String; comp type 0 42 Dis#1 44 BEEP 2000, 2: PAUSE 46 : 48 BIS A%, 2: rem Signed byte 50 BIS A , 6: rem Signed word 52 BIS A$, 14 + 256: rem String; comp type 1 (ignore case) 54 Dis#2 56 : 58 DEFine PROCedure Dis(ch) 60 LOCal i 62 CLS#ch 64 FOR i = 0 TO DIMN(A%) 66 PRINT#ch; A%(i), A(i), A$(i) 68 END FOR i 70 END DEFine Dis 72 : 74 : 100 rem + ------------------------------------------------------------------------ + 102 rem |< BIS >| 104 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 106 rem | Straight (Binary) Insertion Sort | 108 rem | | 110 rem | TAOCP 5.2.1 | 112 rem | | 114 rem | Stable! Sorts arrays of any type. | 116 rem | | 118 rem | Dependency: COMP% | 120 rem + ------------------------------------------------------------------------ + 122 rem | V0.01, pjw, 1993 Apr 23, adapted for SuperBASIC from algorithm | 124 rem | V0.01, pjw, 2023 Aug 19, uses COMP% types | 126 rem + ------------------------------------------------------------------------ + 128 : 130 DEFine PROCedure BIS(arr, type%) 132 LOCal sl, j%, i%, t$ 134 FOR j% = 1 TO DIMN(arr) 136 t$ = arr(j%): i% = j% - 1 138 REPeat sl 140 IF COMP%(t$, arr(i%), type%) >= 0: EXIT sl 142 arr(i% + 1) = arr(i%) 144 i% = i% - 1: IF i% <= -1: EXIT sl 146 END REPeat sl 148 arr(i% + 1) = t$ 150 END FOR j% 152 END DEFine BIS 154 : 156 : Status of This software: ======================== V0.01, pjw, 2023 Jul 28, first release Conditions and DISCLAIMER as per Knoware.no
Generated by QuickHTM, 2023 Aug 19