Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to tell if an integer is even or odd

Status
Not open for further replies.

Nuqe

Technical User
May 6, 2003
57
0
0
CA
I'm looking for a way to determine if an integer is even or odd. i'm doing a print procedure and need to take the number of records in a database and half it, then print each half on different pages. This is easy unless you have an odd number. If i can determine if the recordcount is odd then i can just add 1 as a place holder so i can do the procedure.

any help would be appreciated
NUQE

We all know about the "stupid user" don't we... :)
 
I think I posted this in response to a similar question:


Public Function fnIsEven(inp As Long) As Boolean
fnIsEven = Not (inp Mod 2)
End Function

You will need to add your own error checking etc


________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'People who live in windowed environments shouldn't cast pointers.'
 
Thanks a bunch

Nuqe

We all know about the "stupid user" don't we... :)
 
I'm not sure how VB handles mod. I also do not know how it handles bit testing. But, if all is handled as fast as possible, bit testing should produce less overhead; after all: a number can only be odd if bit 0 has been set....

I think that something like fnIsEven = (inp AND 1& = 0) might be less overhead. Or at least it should be....



Greetings,
Rick
 
I tried both of these ways and neither of them told the difference between even and odd... i don't think i did anything wrong.

Nuqe

We all know about the "stupid user" don't we... :)
 
Private Sub Command1_Click()

returned = IsOdd(10431)
returned = IsOdd(10432)

End Sub

Private Function IsOdd(myValue As Integer)

IsOdd = True
If myValue And 1 Then
IsOdd = False
End If

End Function

bear in mind there is no error checking!!!

good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
Adoozer, this code works, but doesn't allow me to enter a variable into the function
ex.
returned = IsOdd(intblah)

can it be done?

Nuqe

We all know about the "stupid user" don't we... :)
 
actually this worked
returned = IsOdd("" & intRecNum2)
good to go
thanks again

Nuqe

We all know about the "stupid user" don't we... :)
 
um yeah!!

just call the function isOdd with whatever value...

ie

private sub SomeRandomSub()

'value entered in text1
returned=IsOdd(cint(text1.text))

end sub

good luck!!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
what is intrecnum?? you shouldnt need the string or the concatenation(or however its spelt) &

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
well if i dont' do it like this
returned = IsOdd("" & intRecNum2)
then it gives me this error:

Compile error:
ByRef argument type mismatch


intrecnum is just an integer holding number of records.


We all know about the "stupid user" don't we... :)
 
Wait... CInt?? what is that used for
anyways i used it and it worked.. heh
my head hurts

Nuqe

We all know about the "stupid user" don't we... :)
 
cint converts the value to an integer (see MSDN for more info) (which is the default value of my ISODD function and probably the reason you got the byref error!!

ps change this line

Private Function IsOdd(myValue As Integer)

to

Private Function IsOdd(myValue As Integer) as binary

for true properness(is that a real word)

good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
on a side note (sorry to keep bumping this thread) johnwms code (using mod operator) works seemingly as quick as my code!! and b4 reading lazyme's post would have been the way id have suggested!!

just to throw it in the mixer [lol]

good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
doh... well caught VB5.. can you tell its late over here!!! [lol]

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
A General Guide To Excel in VB FAQ222-3383
The Great Date Debate Thread222-368305
File Formats Galore @
 
LazyMe is right. Tested X And 1 = 0 and X Mod 2 = 0 in a loop of 10,000,000 in VB.

X And 1 = 0 took ~0.64 seconds.
X Mod 2 = 0 took ~1.20 seconds.
 

There must be some other factors in that mentioned test...

There is actually no difference in speed between the two methods.
 
Now, I got curious and did some testing myself too. To rule any disturbance, I had myslef test them seperately:

Private Sub cmd_Click()
Static sblnMod As Boolean

Dim lngCounter As Long, lngDummy As Long
Dim sngStart As Single, sngStop As Single

If sblnMod Then
sngStart = Timer

For lngCounter = 0 To 10000000
lngDummy = lngCounter Mod 2
Next lngCounter

sngStop = Timer
Else
sngStart = Timer

For lngCounter = 0 To 10000000
lngDummy = lngCounter And 1
Next lngCounter

sngStop = Timer
End If

Print CStr(sngStop - sngStart), CStr(IIf(sblnMod, "mod", "and"))

sblnMod = Not sblnMod
End Sub


It seems that, indeed, there's a slight difference in processing time in favor of bit testing (although I had expected more...).

I can't get around the fact that accuracy of this test probably is miserable, however, this accounts for both methods and results are constantly in favor of bit testing.

I'm not familiar with the instruction set of the processor, but I'm quite sure that there's an intrinsic bit testing instruction whereas I don't know about an intrinsic mod instruction. Even if there is one, it has to be involving more clock cycles, since it's dividing and checking remains, whereas testing one bit value should be possible in one cycle.


Greetings,
Rick
 
1. Try using a hard coded value. See a difference?

2. MOST important, Did you try your code compiled?

Now you should see a difference between the test you did before, even using a Timer (I use the QueryPerformanceCounter). You should find the "AND" sometimes faster, and the "MOD" other times faster, and an average over many tests they come close enough to the same value that I would say any differences are related to other factors.
Here's the code using the QueryPerformanceCounter and 100,000,000, not 10,000,000 loops, in order to increase the differences (with 10,000 and comiled code using the timer there would probably be an identical average):

Option Explicit

Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
Private Sub Command3_Click()

Static sblnMod As Boolean
Dim StartTicks As Currency
Dim StopTicks As Currency
Dim Frequency As Currency

Dim lngCounter As Long, lngDummy As Long
Dim sngStart As Single, sngStop As Single

If sblnMod Then
QueryPerformanceFrequency Frequency
QueryPerformanceCounter StartTicks

For lngCounter = 0 To 100000000
lngDummy = lngCounter Mod 2
Next lngCounter

QueryPerformanceCounter StopTicks

Else
QueryPerformanceFrequency Frequency
QueryPerformanceCounter StartTicks

For lngCounter = 0 To 100000000
lngDummy = lngCounter And 1
Next lngCounter

QueryPerformanceCounter StopTicks

End If

MsgBox (StopTicks - StartTicks) / Frequency & CStr(IIf(sblnMod, "mod", "and"))

sblnMod = Not sblnMod
End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top