News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Odd or Even

Started by herge, October 13, 2008, 11:35:59 AM

Previous topic - Next topic

fearless

Use AND and BT. Odd numbers expressed in binary always have the rightmost (2^0) bit = 1 and even numbers always have the 2^0 bit = 0.

IsEven MACRO val1:REQ
push eax
mov eax, val1
and eax, 1
bt  eax, 0 ; test lowest bit
jnc Even ; jmp if bit is 0

:Odd
mov edx, FALSE
jmp OddEvenEnd

:Even
mov edx, TRUE

OddEvenEnd:

pop eax
exitm <edx>
ENDM


ƒearless

NightWare

#16
 :eek why AND ?

EDIT :
you can reduce your macro to something like :
IsEven MACRO val1:REQ
xor edx,edx ; edx = 0
bt val1,0 ; test lowest bit
adc edx,edx ; edx = 0+carry
btc edx,0 ; invert bit 0
ENDM

and deduce this macro :
IsOdd MACRO val1:REQ
xor edx,edx ; edx = 0
bt val1,0 ; test lowest bit
adc edx,edx ; edx = 0+carry
ENDM

jj2007

Quote from: NightWare on October 14, 2008, 12:32:50 AM
you can reduce your macro to something like :
IsEven MACRO val1:REQ
xor edx,edx ; edx = 0
bt val1,0 ; test lowest bit
adc edx,edx ; edx = 0+carry
btc edx,0 ; invert bit 0
ENDM


EVEN that is much too ODD for my taste. Since there is a small risk that noobs read this thread, here is the final solution (see herge's reply #4):

      mov ebx, 123
      test ebx, 1
      .if zero?
         print str$(ebx), " is even", 13, 10
      .else
         print str$(ebx), " is odd", 13, 10
      .endif

For the noobs: Some of the earlier posts were written with the agenda "how can I perform simple things in the most complicated way".
For the moderators: Please introduce a smiley saying "Attention, I am pulling your leg"  :lol

sinsi

wow...just...wow
I can't believe the effort that has gone into this topic, all for a "test ebx,1".
The best was introducing edx, but second prize has to go to using all these bt/btc opcodes...
My offering

    test ebx,1  ;test bl,1
    jnz is_oddly_an_odd_number ;you know, 1,11,101,111,1001 ad infinitum
    ;code here for even number


Hey, this is like the "destructive AND vs non-destructive TEST" thing, isn't it. :bg
Light travels faster than sound, that's why some people seem bright until you hear them.

jj2007

Quote from: sinsi on October 14, 2008, 06:17:19 AM
The best was introducing edx, but second prize has to go to using all these bt/btc opcodes...

I am deeply disappointed that you chose to ignore my simple FPU solution, #7.

QuoteHey, this is like the "destructive AND vs non-destructive TEST" thing, isn't it. :bg

How odd that you even thought of that thread :green

jdoe

Quote from: sinsi on October 14, 2008, 06:17:19 AM
wow...just...wow
I can't believe the effort that has gone into this topic, all for a "test ebx,1".
The best was introducing edx, but second prize has to go to using all these bt/btc opcodes...
My offering

    test ebx,1  ;test bl,1
    jnz is_oddly_an_odd_number ;you know, 1,11,101,111,1001 ad infinitum
    ;code here for even number


Hey, this is like the "destructive AND vs non-destructive TEST" thing, isn't it. :bg


For sure, some of this board topics are just fascinating.   :cheekygreen:


sinsi

Still waiting for the sse2 version though.
Light travels faster than sound, that's why some people seem bright until you hear them.

jdoe

Quote from: sinsi on October 14, 2008, 07:03:22 AM
Still waiting for the sse2 version though.


And the code timing because we are still not sure by how many cpu clocks "test ebx,1" will beat them all   :green2


zooba

I think I've got the slowest one. Usually takes a few seconds, but can occasionally take a number of hours, depending on how complicated the number is:

IsOdd PROC number:DWORD
    LOCAL buffer:BYTE[256]

    lea  eax, buffer
    mov  BYTE PTR [eax], 0
    mov  eax, cat$(eax, "Is the number ", ustr$(number), " an odd number?")

    invoke MessageBoxA, 0, eax, chr$("Odd or even?"), MB_YESNO OR MB_ICONQUESTION
   
    .if(eax == IDYES)
        mov  eax, TRUE
    .else
        mov  eax, FALSE
    .endif
   
    ret
IsOdd ENDP


Cheers,

Zooba :U

I haven't actually tested that code, and I don't normally use MASM32's string macros, so apologies if it is all wrong :bg

MichaelW

Considering that this is the Laboratory, you should create a speed-optimized version that displays only the value of the last bit. It would still run slow on some systems, but for most it should be much faster.

eschew obfuscation

jj2007

Quote from: zooba on October 14, 2008, 08:02:40 AM
I think I've got the slowest one. Usually takes a few seconds, but can occasionally take a number of hours, depending on how complicated the number is:

I did some timings, and the results look ODD, it EVEN seems there is some quadratic element:

number       time
123          5'
1234         7'30''
4321         9'00''
12345678     3h30'00''
123454321 --- exception #5


Besides, your code failed miserably for the last number. Zooba, could you please post the complete source?

eaOn

The thread is getting ODD, EVENthough we are only dealing with a simple algo here. :lol

Here's my little contribution. It's a good exercise for a  masm32 starter like me. :P
main proc
    LOCAL num1:DWORD
    mov num1, sval(input("Enter a number : "))
    mov ebx,num1
    and al,1b                          ;logical operation.
    cmp al,1
    jne even1
    je odd
   

odd:
    print str$(ebx)," is odd"
    jmp done

even1:
    print str$(ebx)," is even"


done:

    ret

main endp

It's hard to technically explain it but whenever your value is in odd bit-0 is always set to 1.
For example:
ODD
7d  =0111b
15d=1111b
9d  =1001b


EVEN
10d=1010b
6d  = 0110b

This holds true with large values too. I guess this a matter of common sense nowadays.  :U



All solution is accepted by the way. It's up to the user how to deal with them. If speed is a factor, then use bitwise operators.

drizz

here is an experienced coder contribution :))

.data
szeven db "EVEN",0
szodd db "ODD",0
align 4
msgs dd offset szeven,offset szodd
.code
mov eax,number
and eax,1
mov eax,[msgs+eax*4]
invoke MessageBox,0,eax,0,0


.data?
msgs db 8 dup (?)
.code
mov eax,number
and eax,1
cmp eax,1
sbb eax,eax; 0 if eax >= 1 else -1
and eax,"NEVE"-"DDO"
add eax,"DDO"
mov dword ptr msgs,eax
invoke MessageBox,0,addr msgs,0,0
The truth cannot be learned ... it can only be recognized.

NightWare

Quote from: eaOn on October 14, 2008, 04:35:51 PM
    and al,1b                          ;logical operation.
:lol

Quote from: MichaelW on October 14, 2008, 08:27:29 AM
Considering that this is the Laboratory, you should create a speed-optimized version that displays only the value of the last bit. It would still run slow on some systems, but for most it should be much faster.

:lol i have one !!! here => and eax,1
beside bogdan has said it's difficult to do it faster !

DoomyD

How about...
shr ebx,1
jc _odd_number_