Author Topic: Determining Even or Odd  (Read 7425 times)

0 Members and 1 Guest are viewing this topic.

Hangman

  • Swamp Rat
  • Posts: 566
Determining Even or Odd
« on: October 06, 2006, 09:15:53 PM »
Hey guys, I'm in a bit of a pickle.  I'm about to get swamped (no pun intended   :?  ) with a "need it yesterday" type of project.  This thing will be an ongoing project for the next 6 months.  It's a nightmare, long story.  So I'm trying to put together a couple routines that will help me for the onslaught come Monday morning.

Is there a way to determine a real number be either Even or Odd without having to type in every single number from 1 to 50 ??

Code: [Select]
...
  (setq pt-dist_12 (distance pt1 pt2))
  (setq plate-ctr (/ pt-dist_12 3))
  (setq plate-ctr (fix plate-ctr))
  (progn
    (cond  ( (  ... ;;If plate-ctr is Odd then do something ...
              ( (  ... ;;If plate-ctr is Even then do something else ...
  ))))

Is there a possibility of that or do I need to do something like this ...

Code: [Select]
...
  (setq pt-dist_12 (distance pt1 pt2))
  (setq plate-ctr (/ pt-dist_12 3))
  (setq plate-ctr (fix plate-ctr))
  (progn
    (cond  ( (or (= plate-ctr 1) (= plate-ctr 3) (= plate-ctr 5) (= plate-ctr 7) (= plate-ctr 9)) ;; all the way to 49
                ( ...  do something here ... ))
              ( (or (= plate-ctr 2) (= plate-ctr 4) (= plate-ctr 6) (= plate-ctr 8)  (= plate-ctr 10)) ;; all the way to 50
                ( ...  do something here ... ))
  ))))

Thank you for your thoughts & help.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MickD

  • King Gator
  • Posts: 3640
  • (x-in)->[process]->(y-out) ... simples!
Re: Determining Even or Odd
« Reply #1 on: October 06, 2006, 09:22:59 PM »
is there a modulo operator in lisp??

if num%2 > 0 answer is odd. (where '%' = modulo operator)
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3640
  • (x-in)->[process]->(y-out) ... simples!
Re: Determining Even or Odd
« Reply #2 on: October 06, 2006, 09:33:24 PM »
lisp arithmetic function 'rem' looks like it should do the trick ;)
« Last Edit: October 06, 2006, 09:34:29 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #3 on: October 06, 2006, 09:59:37 PM »
Another spin on the topic:
If the last number is a one, its odd. If its not, then its even.

1: 00000001
2: 00000010
3: 00000011
4: 00000100
...
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #4 on: October 06, 2006, 10:05:55 PM »
(defun odd? (i)
  ;; odd?
  ;; Returns 0 if even and 1 if odd
   (logand i 1))

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Determining Even or Odd
« Reply #5 on: October 06, 2006, 10:19:43 PM »
Code: [Select]
(defun IsEven ( x )
    (zerop (rem x 2))
)


Code: [Select]
...
(setq
    pt-dist_12 (distance pt1 pt2)
    plate-ctr  (fix (/ pt-dist_12 3))
)

(if (IsEven plate-ctr)
    (DoStuffForEvenCondition)
    (DoStuffForOddCondition)
)
...
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MickD

  • King Gator
  • Posts: 3640
  • (x-in)->[process]->(y-out) ... simples!
Re: Determining Even or Odd
« Reply #6 on: October 06, 2006, 10:42:13 PM »
logand would be by far the quickest given the fact you don't need the remainder and division is a slow(er) operation for a cpu, another practical use for 0's and 1's :)
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Hangman

  • Swamp Rat
  • Posts: 566
Re: Determining Even or Odd
« Reply #7 on: October 06, 2006, 11:15:42 PM »
Hey guys, thanks for the quick responses.  Looking over these, I'm think'n MickD is correct, I'd prefer to use the logand function.  I like the post Se7en posted,
Quote
(defun odd? (i)
  ;; odd?
  ;; Returns 0 if even and 1 if odd
   (logand i 1))
But I'm not understanding exactly how it's to work.  I've tried it with several different numbers, but it keeps coming back as Odd.  I don't think I'm working it properly and the examples in the help files don't give me much.  Could you guys post a couple examples for me. ??

Nice post MP, I like the way you did that.  Thanks for the input & help.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Determining Even or Odd
« Reply #8 on: October 06, 2006, 11:16:05 PM »
logand would be by far the quickest given the fact you don't need the remainder and division is a slow(er) operation for a cpu, another practical use for 0's and 1's :)

... but no practical speed difference is realized in lisp --

Elapsed milliseconds / relative speed for 32768 iteration(s):

    (zerop (rem 1 2)) ............... 1438 / 1.01 <fastest>
    (zerop (logand 1 1)) ............ 1453 / 1.00 <slowest>

    (zerop (rem 255 2)) ............. 1437 / 1.01 <fastest>
    (zerop (logand 255 1)) .......... 1453 / 1.00 <slowest>

    (zerop (rem 65535 2)) ........... 1469 / 1.01 <fastest>
    (zerop (logand 65535 1)) ........ 1485 / 1.00 <slowest>

    (zerop (rem 1073741824 2)) ...... 1468 / 1.02 <fastest>
    (zerop (logand 1073741824 1)) ... 1500 / 1.00 <slowest>


:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MickD

  • King Gator
  • Posts: 3640
  • (x-in)->[process]->(y-out) ... simples!
Re: Determining Even or Odd
« Reply #9 on: October 06, 2006, 11:33:14 PM »
layer upon layer upon layer.....

oh well, it was food for thought though. :)

in technical terms, rem/modulo returns the remainder from a division eg 12/10 = 2 and 12/2 = 0.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Hangman

  • Swamp Rat
  • Posts: 566
Re: Determining Even or Odd
« Reply #10 on: October 06, 2006, 11:45:06 PM »
Yeah, well, my head feels like it's going to burst into flames.

K, so, 'rem' might be faster.  I don't think a couple milliseconds is going to make too much of a difference here.  But I'm learn'n someth'n new.

I just found the Logand info  (couldn't find it online, had to revert to an old book written for release 12).
So, the code Se7en posted:
Code: [Select]
(defun odd? (i)
  ;; odd?
  ;; Returns 0 if even and 1 if odd
   (logand i 1))
The 'i', to my understanding, is the integer to be tested ?.
So, one would setq i to an integer, and the 'logand' would test i for an odd bitcode ?.

So I could set my code something like:
Code: [Select]
...
(setq
    pt-dist_12 (distance pt1 pt2)
    plate-ctr  (fix (/ pt-dist_12 3))
)
(setq Odd-Even (logand plate-ctr 1))
(progn
(if (= Odd-Even 0)
    (DoStuffForEvenCondition)
    (DoStuffForOddCondition)
))
...

Hey look, it worked !!!  Too cool.  Thanks guys.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Determining Even or Odd
« Reply #11 on: October 06, 2006, 11:53:19 PM »
Code: [Select]
;; returns t of num is odd
(defun odd? (num)
   (= (logand num 1) 1)
)


Code: [Select]
(print (odd? 1))
(print (odd? 2))
(print (odd? 3))
(print (odd? 4))


Code: [Select]
;; returns t of num is even
(defun even? (num)
   (zerop (logand num 1))
)


Code: [Select]
(print (even? 1))
(print (even? 2))
(print (even? 3))
(print (even? 4))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #12 on: October 07, 2006, 02:07:01 AM »
<snip>
    (zerop (rem 65535 2)) ........... 1469 / 1.01 <fastest>
    (zerop (logand 65535 1)) ........ 1485 / 1.00 <slowest>

    (zerop (rem 1073741824 2)) ...... 1468 / 1.02 <fastest>
</snip>
:)

Hey, wait a min. Well that scenario has got to be slower. Your pinning one boolean test up against two (Native mathematics is the fastest hands down so that can be negated from the test.).

If we pin my one Boole up against your math&Boole i bet i could do better then that.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #13 on: October 07, 2006, 02:09:02 AM »
<snip>
Code: [Select]
;; returns t of num is even
(defun even? (num)
   (zerop (logand num 1))
)
</snip>

One question: Why have a test for both odd and even? ``If its not one...''
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #14 on: October 07, 2006, 02:13:26 AM »
<snip>
The 'i', to my understanding, is the integer to be tested ?.
So, one would setq i to an integer, and the 'logand' would test i for an odd bitcode ?.
</snip>

And returns true if and oly if both tests are true. In the case of `logand ... 1' we are testing to see if the first bit is a one in an int.  (Does that make sence?)

1 = 00000001
2 = 00000010

So

(logand 2 1) returns what?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Determining Even or Odd
« Reply #15 on: October 07, 2006, 08:13:43 AM »
One question: Why have a test for both odd and even? ``If its not one...''

Readability.

Code: [Select]
(If (even? num)
Code: [Select]
(If (not (odd? num))
I don't see it as costing you anything, especially if it pleases you when you read it. :-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Determining Even or Odd
« Reply #16 on: October 07, 2006, 09:03:08 AM »
Readability ... I don't see it as costing you anything, especially if it pleases you when you read it.

True, but ... in the bigger sense it just makes a library bigger than it need be, and while the code in this example is trivial it does mean there is more code to maintain. I would surmise that's why you don't see the compliment to predicate functions in most languages (e.g. exception: vbnet's is/isnot operators), for example in lisp there are no NotBoundP, NotNumberP, NotZeroP ... functions. :)

If we pin my one Boole up against your math&Boole i bet i could do better then that.

Go for it but be aware any performance gains are not realized because of the additional comparison testing one has to do in-situ, so then it comes down to practicality; ease of use. :)

/imo
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Determining Even or Odd
« Reply #17 on: October 07, 2006, 10:32:08 AM »
Another thing to consider --

Code: [Select]
(   (lambda ( / IsEvenRem IsEvenLogand TestFoo )

        (defun IsEvenRem (x) (zerop (rem x 2)))

        (defun IsEvenLogand (x) (zerop (logand 1 x)))
       
        (defun TestFoo ( foo x )       
            (princ
                (strcat
                    "Testing:" (vl-prin1-to-string foo) "\n\n"
                )   
            )
            (repeat 10
                (princ
                    (strcat     
                        (rtos (setq x (+ x 0.5)) 2 1)
                        " is "
                        (if (foo x) "even\n" "not even\n")
                    )
                )
            )
            (princ "\n")
            (princ)
        )
       
        (TestFoo IsEvenRem 0)
       
        (TestFoo IsEvenLogand 0)
       
    )
)
   

Testing:#<SUBR @10327c94 ISEVENREM>

0.5 is not even
1.0 is not even
1.5 is not even
2.0 is even
2.5 is not even
3.0 is not even
3.5 is not even
4.0 is even
4.5 is not even
5.0 is not even

Testing:#<SUBR @10327ca8 ISEVENLOGAND>

Backtrace:
[0.64] (VL-BT)
[1.60] (*ERROR* "bad argument type: fixnump: 0.5")
[2.55] (_call-err-hook #<SUBR ... *ERROR*> "bad argument type: fixnump: 0.5")
[3.49] (sys-error "bad argument type: fixnump: 0.5")
:ERROR-BREAK.44 nil
[4.41] (logand 1 0.5)
[5.35] (LOGAND 1 0.5)
[6.29] (FOO 0.5)
[7.24] (TESTFOO #<SUBR @103a4f8c ISEVENLOGAND> 0)
[8.18] (#<SUBR @103f91e0 -lambda->)
[9.15] (#<SUBR @103f9258 -rts_top->)
[10.12] (#<SUBR @0de62334 veval-str-body> "((lambda ..." T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)


Should reals (or integers larger than 2147483647, less than -2147483647) be excluded from an even test? I don't know, what's your call?

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Determining Even or Odd
« Reply #18 on: October 07, 2006, 11:03:39 AM »
Readability ... I don't see it as costing you anything, especially if it pleases you when you read it.

True, but ... in the bigger sense it just makes a library bigger than it need be, and while the code in this example is trivial it does mean there is more code to maintain. I would surmise that's why you don't see the compliment to predicate functions in most languages (e.g. exception: vbnet's is/isnot operators), for example in lisp there are no NotBoundP, NotNumberP, NotZeroP ... functions. :)

I don't practice that but for the sake of discussion, you could implement it this way & not worry about the maintenance issue.

Code: [Select]
(defun NotBoundP (arg)
  (not (BoundP arg))
)

(defun NotNumberP (arg)
  (not (NumberP arg))
)

(defun NotZeroP (arg)
  (not (ZeroP arg))
)

I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10655
Re: Determining Even or Odd
« Reply #19 on: October 07, 2006, 11:16:59 AM »
*zing* ... *lmao* (I didn't see that coming)

My call: no. Not in this case. I say that because of the orig. scope of the request. The author is asking for a test to test numbers from 1-50. HOWEVER! i know that's the ``easy'' route here. -i.e. i know most people are most likely not going to ensure only int's get tested if they just toss this into their library and use it later but he does use the `fix' procedure in this case so...but, again that's kind of a cop out. Maybe i should just note that in my header that if you plan to use this or if there is a chance that there will be other types of numbers besides int's tested please seek other methods.

It all comes down to personal preference. When creating applications i prefer the proced's to be as ``little'' as they can (And by that i mean to not add too much more as far as scope goes) to save on readability and time. Its not that I would much rather come back with a diff revision later, but i like to keep my code as lean as possible.

I guess what it comes down to is: `Fun' is fun, but `production' is diff. ...I love creating procedures that take into account alot of diff situations for fun, but in production I create what needes to be created.

That's why I love using block structure in my code; I can come back and totaly change the application by adding a few lines here and a few there.

For example.

Orig: (defun odd? (i) (logand i 1) )
New:
Code: [Select]
(defun odd? ( i )
  ;; determine if a number is odd?
  ;; scope: numbers 1 -- 50 only
  (if (and (>= i 0) (<= i 50))
     (logand i 1)
     '*Error* ) )

I dont know, its a wash I suppose.

CAB, It creates maintence issues with the code. Its a bit redundant. HOWEVER! if  you are in need of a way to ``test for evens'' in a diff proced, then i can see using it. (Im saying try to name your procedures in the spirit of your application. -e.g. if you spend 100 lines `talking about evens' and then all of a sudden you `test for odd' becuse you were to lazy to alter a library function then...)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org