[Back to SORTING SWAG index] [Back to Main SWAG index] [Original]
{
Here's my solution to your "contest". The first I'm rather proud
of, it incorporates bAsm to beat your devilshly efficient CASE
Implementation by a factor of 2x.
The second, I am rather disappointed With as it doesn't even come
CLOSE to TP's inbuilt STR Function. (The reason, I have found, is
because TP's implementaion Uses a table based approach that would
be hard to duplicate With Variable radixes. I am working on a
Variable radix table now)
****************************************************************
Converts String pointed to by S into unsigned Integer V. No
range or error checking is performed. Caller is responsible for
ensuring that Radix is in proper range of 2-36, and that no
invalid Characters exist in the String.
****************************************************************
}
Type
pChar = ^chr_Array;
chr_Array = Array[0..255] of Char;
Byte_arry = Array[Char] of Byte;
Const
sym_tab : Byte_arry = (
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,
0,0,0,0,0,0,0,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,0,0,0,0,0,0,10,11,12,13,
14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0
);
Procedure RadixVal(Var V:LongInt; S:PChar;Radix:Byte);
Var
digit :Byte;
p, p2 :Pointer;
hiwd, lowd :Word;
begin
V := 0;
p := @S^[0];
p2 := @V;
Asm
les bx, p2
push ds
pop es
lds si, p
@loop3:
lea di, [sym_tab]
xor ah, ah
lodsb
cmp al, 0
je @quit
add di, ax { index to Char position in table }
mov al, Byte PTR [di]
mov digit, al
xor ah, ah
mov al, Radix
mov cx, ax
mul Word PTR [bx]
mov lowd, ax
mov hiwd, dx
mov ax, cx
mul Word PTR [bx+2] { mutliply high Word With radix }
add hiwd, ax { add result to previous result - assume hi result 0 }
mov ax, lowd
mov dx, hiwd
add al, digit { add digit value }
adc ah, 0 { resolve any carry }
mov [bx], ax { store final values }
mov [bx+2], dx
jmp @loop3
@quit:
end;
end;
{
****************************************************************
Convert unsigned Integer in V to String pointed to by S.
Radix determines the base to use in the conversion. No range
checking is performed, the caller is responsible For ensuring
the radix is in the proper range (2-36), and that V is positive.
****************************************************************
}
Type
Char_arry = Array[0..35] of Char;
Const
symbols :Char_arry = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
Procedure RadixStr(V:LongInt; S:PChar; Radix:Byte);
Var
digit, c :Byte;
ts :String;
p, p2 :Pointer;
begin
c := 255;
ts[255] := #0;
p := @V;
p2 := @ts[0];
Asm
push ds
lea si, [symbols]
les bx, p
les di, p2
add di, 255
std
xor cx, cx
mov cl, Radix
@loop:
SEGES mov ax, Word PTR [bx]
SEGES mov dx, Word PTR [bx+2]
div cx
SEGES mov Word PTR [bx], ax
SEGES mov Word PTR [bx+2], 0
mov digit, dl
push si
xor ah, ah
mov al, digit
add si, ax
movsb
pop si
dec c
SEGES cmp Word PTR [bx], 0
je @done
SEGES cmp Word PTR [bx+2], 0
je @loop
@done:
pop ds
end;
ts[c] := Chr(255-c);
p := @S^[0];
Asm
push ds
cld
lds si, p2
les di, p
xor bx, bx
mov bl, c
add si, bx
mov cx, 256
sub cl, c
sbb ch, 0
rep movsb
pop ds
end;
end;
[Back to SORTING SWAG index] [Back to Main SWAG index] [Original]