Mike,
this appears to work.
The main code does the job on a full sized LONG in about 40clks. On a 5 digit LONG it's about half that. You can save a bit more if you don't need signs by cutting out that part.
The problem is that if you want to call it as a PB function with that function returning a dynamic string as the answer then the call/return process is taking 8 times longer than the conversion.
If you really want speed you need to send the answer to the function as one of the parameters so there's only 1 string being created instead of 3.
Ideally, you'd use ASCIIZ stings as the're faster.
You could also try inlining the code and you'll then get the best possible speed.
Paul.
------------------
[This message has been edited by Paul Dixon (edited July 31, 2007).]
this appears to work.
The main code does the job on a full sized LONG in about 40clks. On a 5 digit LONG it's about half that. You can save a bit more if you don't need signs by cutting out that part.
The problem is that if you want to call it as a PB function with that function returning a dynamic string as the answer then the call/return process is taking 8 times longer than the conversion.
If you really want speed you need to send the answer to the function as one of the parameters so there's only 1 string being created instead of 3.
Ideally, you'd use ASCIIZ stings as the're faster.
You could also try inlining the code and you'll then get the best possible speed.
Paul.
Code:
FUNCTION FastLong2Str( BYVAL LongVar AS LONG ) AS STRING STATIC a AS ASCIIZ*20 STATIC CalledBefore AS LONG IF NOT CalledBefore THEN a$="00000000000000" CalledBefore=-1 END IF !mov eax,LongVar 'get number !lea ecx,a$ 'get pointer to answer string !jmp over chartab: !dd "00","10","20","30","40","50","60","70","80","90" !dd "01","11","21","31","41","51","61","71","81","91" !dd "02","12","22","32","42","52","62","72","82","92" !dd "03","13","23","33","43","53","63","73","83","93" !dd "04","14","24","34","44","54","64","74","84","94" !dd "05","15","25","35","45","55","65","75","85","95" !dd "06","16","26","36","46","56","66","76","86","96" !dd "07","17","27","37","47","57","67","77","87","97" !dd "08","18","28","38","48","58","68","78","88","98" !dd "09","19","29","39","49","59","69","79","89","99" over: 'on entry eax=number to convert, ecx=pointer to answer buffer (minimum 12 bytes) 'on exit, eax,ecx,edx are undefined, all other registers are preserved. 'answer is in location pointed to by ecx on entry sdword: 'do a signed DWORD to ASCII !or eax,eax 'test sign !jns udword 'if +ve, continue as for unsigned !neg eax 'else, make number positive !mov byte ptr [ecx],"-" 'include the - sign !inc ecx 'update the pointer udword: 'unsigned DWORD to ASCII !push edi 'save registers that need to be saved !push esi !mov esi,ecx 'get pointer to answer !mov edi,eax 'save a copy of the number !mov edx, &hD1B71759 '=2^45\10000 13 bit extra shift !mul edx 'gives 6 high digits in edx !mov eax,&h68DB9 '=2^32\10000+1 !shr edx,13 'correct for multiplier offset used to give better accuracy !jz short skiphighdigits 'if zero then don't need to process the top 6 digits !mov ecx,edx 'get a copy of high digits !imul ecx,10000 'scale up high digits !sub edi,ecx 'subtract high digits from original. EDI now = lower 4 digits !mul edx 'get first 2 digits in edx !mov ecx,100 'load ready for later !jnc short next1 'if zero, supress them by ignoring !cmp edx,9 '1 digit or 2? !ja short ZeroSupressed '2 digits, just continue with pairs of digits to the end !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dh 'but only write the 1 we need, supress the leading zero !inc esi 'update pointer by 1 !jmp short ZS1 'continue with pairs of digits to the end next1: !mul ecx 'get next 2 digits !jnc short next2 'if zero, supress them by ignoring !cmp edx,9 '1 digit or 2? !ja short ZS1a '2 digits, just continue with pairs of digits to the end !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dh 'but only write the 1 we need, supress the leading zero !inc esi 'update pointer by 1 !jmp short ZS2 'continue with pairs of digits to the end next2: !mul ecx 'get next 2 digits !jnc short next3 'if zero, supress them by ignoring !cmp edx,9 '1 digit or 2? !ja short ZS2a '2 digits, just continue with pairs of digits to the end !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dh 'but only write the 1 we need, supress the leading zero !inc esi 'update pointer by 1 !jmp short ZS3 'continue with pairs of digits to the end next3: skiphighdigits: !mov eax,edi 'get lower 4 digits !mov ecx,100 !mov edx,&h28F5C29 '2^32\100 +1 !mul edx !jnc short next4 'if zero, supress them by ignoring !cmp edx,9 '1 digit or 2? !ja short ZS3a '2 digits, just continue with pairs of digits to the end !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dh 'but only write the 1 we need, supress the leading zero !inc esi 'update pointer by 1 !jmp short ZS4 'continue with pairs of digits to the end next4: !mul ecx 'this is the last pair so don't supress a single zero !cmp edx,9 '1 digit or 2? !ja short ZS4a '2 digits, just continue with pairs of digits to the end !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dh 'but only write the 1 we need, supress the leading zero !mov byte ptr [esi+1],0 'zero terminate string !jmp short xit 'all done ZeroSupressed: !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dx !add esi,2 'write them to answer ZS1: !mul ecx 'get next 2 digits ZS1a: !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dx 'write them to answer !add esi,2 ZS2: !mul ecx 'get next 2 digits ZS2a: !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dx 'write them to answer !add esi,2 ZS3: !mov eax,edi 'get lower 4 digits !mov edx,&h28F5C29 '2^32\100 +1 !mul edx 'edx= top pair ZS3a: !mov edx,chartab[edx*4] 'look up 2 digits !mov [esi],dx 'write to answer !add esi,2 'update pointer ZS4: !mul ecx 'get final 2 digits ZS4a: !mov edx,chartab[edx*4] 'look them up !mov [esi],dx 'write to answer !mov byte ptr [esi+2],0 'zero terminate string xit: !pop esi 'restore used registers !pop edi sdwordend: FUNCTION=a$ '!ret END FUNCTION
[This message has been edited by Paul Dixon (edited July 31, 2007).]
Comment