News:

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

Main Menu

Weird result of calculating exponentiation

Started by anta40, February 22, 2013, 08:41:12 PM

Previous topic - Next topic

anta40

I write a little code to calculate exponentiation

include \masm32\include\masm32rt.inc

.data
fmt  db "%d",0
num1 dd 17
num2 dd 0

.code
Start:
mov eax, [num1]
    mov ebx, [num2]
    mov ecx, eax

Check:
    cmp ebx, 1
    jg Multiply
    je Done

Multiply:
    imul eax, ecx
    dec ebx
    jmp Check

Done:   
invoke crt_printf,addr fmt, eax
invoke ExitProcess, 0
end Start


Both inputs, num1 and num2 are assumed to be non-negative integers.
And let's set num2 to a fixed value: 0

As we know from math, any number raised to the power of zero = 1.
Now, the output of the code is 1 if num1 is odd, otherwise 0.

Is this a bug or simply a misunderstanding in assembly?

Tested with jwasm 2.10 and ml 11, FYI.

dedndave

well - most values raised to a power of 0 are 1   :biggrin:
there is a lot of disagreement about 00
some say it is 1, some say it is undefined, and a few say it should be 0
i say it should be whatever makes your function appear continuous - lol
so - it depends on what the use is

at any rate, you have to test for that special case and set the result in your code

also.....
maybe i am missing something in your loop, but i think you want to subtract 1 from the exponent before the loop
this is because you have already raised it once by copying the contents from ECX to EAX
the result of the first loop pass will be squared

dedndave

if you want to speed up evaluation of very large exponents, you might be interested in my Ling Long Kai Fang method....

http://masm32.com/board/index.php?topic=222.msg978#msg978

sinsi

Init EAX to 1 and ECX to num1.
Test for EBX=0 at the start of the loop.

RuiLoureiro

Hi anta40,

    «Is this a bug or simply a misunderstanding in assembly?»

    .   It is a question of math and how to implement it

    First of all, to be clear, we need to give other names to num1 and num2

    num1 = base
    num2 = exponent
   
    «Both inputs, base and exponent are assumed to be non-negative integers.»
   
                                                                       
    As far as i understood     
                                                                            exponent
    you want to calculate base^exponent = base                  = result

    and both are positive integers.

    For example, if base = 5 and exponent = 3
   
    it means we need to do this:

                 result = base * base * base  ( exponent times = 3 times )

    It is clear that what we need to do is to multiply base 3 times

    So if we do ecx = exponent - 1 = 2  and eax = base we need only to do this:


            mov     eax, 1          ; this is the result if exponent=0
            mov     ecx, exponent
            sub     ecx, 1
            js      _exit           ; if exponent = 0 => exit and EAX = 1
            ;
            mov     eax, base
            mov     ebx, eax        ; ebx = eax
            ;
    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------
    _exit: 

    Have a nice work  :t
    If you want, search this forum for "The calculator" ...


include \masm32\include\masm32rt.inc

.data
fmt  db "%d",0

exponent1   dd 3
base1       dd 5

exponent2   dd 17
base2       dd 0

exponent3   dd 0
base3       dd 10000

.code
Start:

            mov     eax, 1          ; this is the result if exponent1=0
            mov     ecx, exponent1
            sub     ecx, 1
            js      short done1
            ;
            mov     eax, base1
            mov     ebx, eax        ; ebx = eax
            ;
    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------
    done1: 

      invoke crt_printf,addr fmt, eax
            inkey
;-------------------------------------------------
            mov     eax, 1          ; this is the result if exponent2=0
            mov     ecx, exponent2
            sub     ecx, 1
            js      short done2
            ;
            mov     eax, base2
            mov     ebx, eax        ; ebx = eax
            ;
    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------
    done2: 

      invoke crt_printf,addr fmt, eax
            inkey
;-------------------------------------------------
            mov     eax, 1          ; this is the result if exponent3=0
            mov     ecx, exponent3
            sub     ecx, 1
            js      short done3
            ;
            mov     eax, base3
            mov     ebx, eax        ; ebx = eax
            ;
    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------
    done3: 

      invoke crt_printf,addr fmt, eax
            inkey
         
       invoke ExitProcess, 0
;-----------------------------------------------
end     Start

anta40

Hi RuiLoureiro,

I found my mistake.

Check:
    cmp ebx, 1
    jg Multiply
    je Done


Obviously it won't give the correct result if ebx (the exponent) is zero  :redface:
BTW, what do @@ and @B mean?

jj2007

Quote from: anta40 on February 23, 2013, 01:46:44 AMwhat do @@ and @B mean?

    jmp @F  ; jump forward to...
    ...
@@:   ... ; the next anonymous label.
    ...
    jxx @B  ; jump back to the label above

RuiLoureiro

jj2007: how are you ?  ;)
           
Hi anta40,
                 jj2007 gave the answer to you

meanwhile:  B means Backward: to jump to the nearest @@ backward
             and F means Forward:  to jump to the nearest @@ forward

@@:
        ...
        ...
        jmp       @B   ; jump to the previous @@

Is it clear ?

anta40

Thanks jj & rui.

It's clear now. Both "@@" and "@B" are quite difficult to be Googled  :redface:

RuiLoureiro

Quote from: anta40 on February 23, 2013, 02:36:55 AM
Thanks jj & rui.

It's clear now. Both "@@" and "@B" are quite difficult to be Googled  :redface:
Yes, have a nice work ! :t

dedndave

anta,
here is a link to the Masm Programmer's Guide
http://dedndave.x10host.com/MASMProgGuide.zip

it says version 6.1
most of the stuff still applies
ms hasn't updated the manual with the masm versions   ::)

raymond

anta40

You must remember that by using "imul eax, ecx", your results will be wrong when they start to exceed 32 bits.
The other suggestion by RuiLoureiro:

    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------

would also yield wrong results once you start exceeding 32 bits for the answer.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

RuiLoureiro

Quote from: raymond on February 23, 2013, 11:44:06 AM
anta40

You must remember that by using "imul eax, ecx", your results will be wrong when they start to exceed 32 bits.
The other suggestion by RuiLoureiro:

    @@:     mul     ebx
            sub     ecx, 1
            jnz     short @B
            ; -------------
            ; result in eax
            ; -------------

would also yield wrong results once you start exceeding 32 bits for the answer.
Hi raymond,
                                  We need to leave something to him 
                                  because he likes to do that hard work ! ;)

dedndave

when it comes to exponentials, 4,294,967,295 is fairly small   :P

Gunther

Quote from: dedndave on February 24, 2013, 12:47:10 AM
when it comes to exponentials, 4,294,967,295 is fairly small   :P

yes, and 00 is any case a not determined value.

Gunther
You have to know the facts before you can distort them.