News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Convert decimal to base 5?

Started by anta40, May 18, 2013, 01:10:52 PM

Previous topic - Next topic

anta40

Quote from: RuiLoureiro on May 18, 2013, 09:11:58 PM
«div  ecx»  divide  edx:eax by ecx 
so do this

xor   edx, edx
div    ecx
-----------------
and do this also
push ecx
print ....  ; <---destroys ecx
pop   ecx

it is safe if we use  ebx or esi or edi

Hmm I think I stil don't get it right...

L2:
    xor edx, edx
    div ecx
    push ecx
    push edx
    print str$(edx)
    pop edx
    pop ecx
    jmp L1


:redface:

dedndave

these functions may (and usually do) destroy EAX, ECX, EDX
they preserve EBX, EBP, ESI, and EDI
L2:
    xor edx, edx
    div ecx
    push eax
    push ecx
    push edx
    print str$(edx)
    pop edx
    pop ecx
    pop eax
    jmp L1

RuiLoureiro

anta40,
This is your code

Quote
include \masm32\include\masm32rt.inc
.686
.code
start:
    ;xor edx,edx
    mov eax, 123   ; number to convert
    ;mov ecx, 5      ; base
    mov ebx, 5           ; base ebx=5  ebx is safe
L1:
    cmp eax, 0      ; if number is still > 0?
    ;jg L2         ; yes. keep dividing   
    jl L3         ; done

L2:
       xor edx, edx
        div ebx         ; number = number eax / base ebx

        push eax    ; preserve the quotient EAX
        ;
             print str$(edx)           ; show the remainder edx
        ;
        pop eax     ; preserve the quotient EAX
        jmp L1

L3:
    exit
end start

dedndave

what you are probably missing is to convert the binary remainder to ASCII before storing it

Base5   PROC USES EDI dwValue:DWORD,lpBuffer:LPSTR

;the buffer pointed to by lpBuffer should be at least 15 bytes long
;a pointer to the first base 5 ASCII digit is returned in EAX

        mov     edi,lpBuffer
        mov     ecx,5
        add     edi,14
        mov     eax,dwValue
        mov     [edi],ch

Base50: xor     edx,edx
        dec     edi
        div     ecx
        or      dl,30h        ;make it an ASCII char
        or      eax,eax
        mov     [edi],dl
        jnz     Base50

        xchg    eax,edi
        ret

Base5   ENDP


of course, if you use the str$ macro, it does that for you
if you want to see the dividend, quotient, and remainder at each step...
Base50: push    ecx
        push    eax
        print   str$(eax),32
        pop     eax
        pop     ecx

        xor     edx,edx
        dec     edi
        div     ecx

        push    ecx
        push    eax
        push    edx
        push    edx
        print   str$(eax),32
        pop     edx
        print   str$(edx),13,10
        pop     edx
        pop     eax
        pop     ecx

        or      dl,30h        ;make it an ASCII char
        or      eax,eax
        mov     [edi],dl
        jnz     Base50

RuiLoureiro

Dave,

      This is a work to you
     
      For base x digits a,b,c,d,e we have
     
(eq. 5) abcde (base x ) = a x^4 + b x^3 + c x^2 + d x + e

     =>

(eq. 6) abcde (base x ) = x(x(x(x(a) + b) + c) +d) + e

     Whats your general magic rule to get the digits p,q,r,s,t,u,v... of base y.

dedndave

that equation looks worse than it is - lol
it's really simple, once you get the hang of it

i wrote this document a few years ago, when i was working on the bignum to ascii routines
hope it helps   :t

dedndave

i might add.....

ling long kai fang is most efficient when working with very large values
for smaller values, like single dwords, the "divide-and-conquer" method can be more efficient
well - just don't use the DIV instruction - lol
for an example of what i mean, have a look at Base5b posted above
it uses divide-and-conquer, but uses mutliply-to-divide and a larger base (25)
if we really wanted it to be fast, we might divide by 625 and use a larger look-up table   :P