Announcement

Collapse
No announcement yet.

Any reason not to use XOR?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Any reason not to use XOR?

    Hello Forum,

    I always thought that the simplest way to set a variable to either 0 or 1 was with the XOR function, as in the following snippet:

    Code:
    %LIGHT_ON  = 0
    %LIGHT_OFF = 1
    
    TYPE Lights
      nStatus as LONG                   ' Must be either %LIGHT_ON or %LIGHT_OFF
    END TYPE
    
    SUB SetLightStatus( nLightStatus as long )
    
      gLight.nStatus = 0 XOR nLightStatus
    
    END SUB
    
    
    ' Usage:
    
    SetLightStatus %LIGHT_ON                         ' Set light status to on
    
    '             or            
    
    SetLightStatus %LIGHT_OFF                        ' Set light status to off
    This way gLight.nStatus can only be set to either 0 or 1 (%LIGHT_ON or %LIGHT_OFF) so it's also a form of data checking. I have used this technique in .DLL's used by other parties.

    However, it has been suggested (by the young "bulls") that XOR is old-fashioned and that I should be using in-built functions like IIF() or SWITCH() or even a simple IF..THEN statement, but I can't see why.

    Surely XOR is not that hard to understand and (from memory) it relates directly to the assembler command - XOR - and must be very effiecient.

    Is there a better way of doing this in PowerBASIC?


    Pat

  • #2
    XOR is one of the tools, and if it's the best tool for the job, use it.
    Rod
    I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

    Comment


    • #3
      Usually the XOR operator is better in a toggle type situation. Although it can be used as you've shown, it's definitely faster to directly set the value when you don't care about its previous state:
      Code:
      gLight.nStatus = %LIGHT_ON
      'or
      gLight.nStatus = %LIGHT_OFF

      Comment


      • #4
        I use it all the time, especially to flip state on a menu.

        Code:
        Case %ID_ExcludeTitle
          If Cb.CtlMsg = %BN_Clicked Then   'flip check status
             ExcludeTitle& = ExcludeTitle& Xor 1
             Menu Set State hMenuSyntax, ByCmd %ID_ExcludeTitle, ExcludeTitle&*8
           End If
        It gives me a multiplier (1 or 0) to use to set a value of 0 or 8 (check state).

        Comment


        • #5
          Code:
          LightOn = %TRUE | %FALSE
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            I prefer this syntax:
            Code:
            ExcludeTitle& = NOT ExcludeTitle&   'produces -1 or 0
            Menu Set State hMenuSyntax, ByCmd %ID_ExcludeTitle, -ExcludeTitle&*8  'produces 8 or 1
            It's more readable IMO, and in a case like yours, where the code would not be called repeatedly in a short time frame, the number of lost CPU cycles -- if any -- would be trivial.

            -- Eric
            "Not my circus, not my monkeys."

            Comment


            • #7
              In this test,

              NOT 0 gives -1
              NOT 1 gives -2

              Code:
              MsgBox Str$(Not 0)
              MsgBox Str$(Not 1)
              Did you mean something else?

              Comment


              • #8
                Sorry MCM,

                But I didn't understand your response. Would you clarify what you meant?

                Comment


                • #9
                  gLight.nStatus = 0 XOR nLightStatus

                  If the zero is hard coded, you might as well just use:

                  gLight.nStatus = nLightStatus
                  Bernard Ertl
                  InterPlan Systems

                  Comment


                  • #10
                    >But I didn't understand your response. Would you clarify what you meant?

                    Why mess with XOR when %TRUE or %FALSE will do?
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      LightOn = %TRUE | %FALSE

                      I think the question is...."How the heck is that used????"

                      inquiring minds would like to know
                      Engineer's Motto: If it aint broke take it apart and fix it

                      "If at 1st you don't succeed... call it version 1.0"

                      "Half of Programming is coding"....."The other 90% is DEBUGGING"

                      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                      Comment


                      • #12
                        Thanks for the response.

                        While direct usage is the simples, as in:

                        Code:
                        gLight.nStatus = nLightStatus
                        it does not do any sort of checking that nLightStatus is either %LIGHT_ON or %LIGHT_OFF, as mentioned in my original post. (The code snippet I originally provided was simply to demonstrate my problem.)

                        The actual code is used in setting a variety of flags, with the code usually sitting in a dll used by third parties. I could redo the code, like:
                        Code:
                        FUNCTION SetLightStatus( nLightStatus as long ) EXPORT AS LONG
                        
                          FUNCTION = %OK                           ' Set default response
                        
                          IF (nLightStatus = %LIGHT_ON OR nLightStatus = %LIGHT_OFF ) THEN
                        
                            gLight.nStatus = nLightStatus
                        
                          ELSE
                        
                            FUNCTION = %FAILED_BAD_PARAMETER
                        
                          END IF
                        
                        
                        END FUNCTION
                        but when you have many paramenters to check the code becomes messy. Using XOR forces the TRUE or FALSE staus. I could also use SELECT..CASE. It was suggested I use:

                        Code:
                        gLight.nStatus = IIF&( nLightStatus = 0, %LIGHT_ON, %LIGHT_OFF )
                        It was also suggested that I use the SWITCH statement, which I've never used before, but it looked congested.

                        Anyhow, I take it from your responses that XOR is still used, appears suitable for the job and function nicely.

                        Thanks,


                        Pat

                        Comment


                        • #13
                          Gary --

                          > NOT 0 gives -1
                          > NOT 1 gives -2
                          > Did you mean something else?

                          No.

                          NOT 0 gives -1
                          NOT -1 gives 0

                          So the value of the variable toggles between those two values, which are the "natural" True and False values for all signed integers.

                          The math in my Menu Set State line has an added minus-sign to produce 0 or positive 8, which are the values that are required by the API.

                          There's nothing wrong with using XOR, I just think that NOT is more intuitive and human-readable. For example "IF NOT ExcludeTitle& THEN" reads almost like a plain-English sentence.

                          -- Eric
                          "Not my circus, not my monkeys."

                          Comment


                          • #14
                            >For example "IF NOT ExcludeTitle& THEN" reads almost like a plain-English sentence.

                            Sure, if it's Master Yoda speaking.....
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              FWIW, ISTRUE() and ISFALSE() exist precisely to deal with "NOT didn't work the way I thought it would"
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Why all that fuss about a YES or NO flag ?????
                                Old QB45 Programmer

                                Comment


                                • #17
                                  Sorry Eric, I didn't see the minus sign to the left of the word - so I see how yours works.

                                  Comment

                                  Working...
                                  X