Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. Bitwise AND in an If/Else block

Bitwise AND in an If/Else block

Scheduled Pinned Locked Moved Visual Basic
questioncsharptutorial
16 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Dave Kreskowiak

    If there is no explicit comparison in the condition expression, it is automatically compared to zero. Non-zero values result in True, zero results in False. Your expressions seem to be dependant on having a bit be 0 or 1. You could rewrite your expression to be a bit more explicit by specifying what the result of the bitwise operation should be. For example, if you need to check the 7th bit for a 1, then you would use something like:

    Private Const MASK As Integer = &H40
    
    If (someValue And MASK) = MASK Then
        ' code if bit is enabled
    End If
    

    A guide to posting questions on CodeProject[^]
    Dave Kreskowiak

    T Offline
    T Offline
    treddie
    wrote on last edited by
    #3

    But that is similar to the following (in principal), which failed to execute the cotained code when the result was zero: If ValueA And MaskA = 0 Then ' Do stuff. End if

    L 1 Reply Last reply
    0
    • T treddie

      But that is similar to the following (in principal), which failed to execute the cotained code when the result was zero: If ValueA And MaskA = 0 Then ' Do stuff. End if

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #4

      See http://msdn.microsoft.com/en-us/library/fw84t893.aspx[^], comparison operators come before logical bitwise. Your code needs to be:

      If (ValueA And MaskA) = 0 Then
      ' or
      If Not (ValueA And MaskA) Then

      Use the best guess

      T 1 Reply Last reply
      0
      • L Lost User

        See http://msdn.microsoft.com/en-us/library/fw84t893.aspx[^], comparison operators come before logical bitwise. Your code needs to be:

        If (ValueA And MaskA) = 0 Then
        ' or
        If Not (ValueA And MaskA) Then

        Use the best guess

        T Offline
        T Offline
        treddie
        wrote on last edited by
        #5

        If (ValueA And MaskA) = 0 Then ' or If Not (ValueA And MaskA) Then After testing, the first example works, the second does not. For the first one, I see now the importance of hierarchy and the parens. For the second, I don't think it works because it is performing a binary NOT on the result, thus turning it into a negative number (or just a huge unsigned integer). At any rate, since it is now a non-zero number, the final condition is "True", and the intended action fails.

        B D L 3 Replies Last reply
        0
        • T treddie

          If (ValueA And MaskA) = 0 Then ' or If Not (ValueA And MaskA) Then After testing, the first example works, the second does not. For the first one, I see now the importance of hierarchy and the parens. For the second, I don't think it works because it is performing a binary NOT on the result, thus turning it into a negative number (or just a huge unsigned integer). At any rate, since it is now a non-zero number, the final condition is "True", and the intended action fails.

          B Offline
          B Offline
          Bernhard Hiller
          wrote on last edited by
          #6

          Show the values of ValueA and MaskA you used for your test. Do you understand that (6 AND 5) = 4?

          1 Reply Last reply
          0
          • T treddie

            If (ValueA And MaskA) = 0 Then ' or If Not (ValueA And MaskA) Then After testing, the first example works, the second does not. For the first one, I see now the importance of hierarchy and the parens. For the second, I don't think it works because it is performing a binary NOT on the result, thus turning it into a negative number (or just a huge unsigned integer). At any rate, since it is now a non-zero number, the final condition is "True", and the intended action fails.

            D Offline
            D Offline
            Dave Kreskowiak
            wrote on last edited by
            #7

            treddie wrote:

            After testing, the first example works, the second does not

            Oh, it works, just not the way to think it does. The result of (ValueA And MaskA) results in an integer value, not True/False. That integer is compared to zero. If the result of the expression is non-zero, True is returned. The Not operator will invert that to False. If the result of the expression is zero, False is returned, then inverted to True by the Not operator. Withouting seeing the values of ValueA and Mask, it's pretty much all we can tell you.

            A guide to posting questions on CodeProject[^]
            Dave Kreskowiak

            T 1 Reply Last reply
            0
            • T treddie

              If (ValueA And MaskA) = 0 Then ' or If Not (ValueA And MaskA) Then After testing, the first example works, the second does not. For the first one, I see now the importance of hierarchy and the parens. For the second, I don't think it works because it is performing a binary NOT on the result, thus turning it into a negative number (or just a huge unsigned integer). At any rate, since it is now a non-zero number, the final condition is "True", and the intended action fails.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #8

              treddie wrote:

              After testing, the first example works, the second does not.

              You need to show us the values of ValueA and MaskA, so we can try to figure out why.

              Use the best guess

              1 Reply Last reply
              0
              • T treddie

                I have to admit, this is probably about as basic as it gets, but I must confess ignorance on this, and I cannot seem to find an answer anywhere. It goes like this: I have an If/EndIf block: If ValueA And MaskA Then ' Do stuff. End if Now, I look at that and my first reaction is to knee-jerk and expect that the above If-line is written incorrectly since a bitwise operation has been evaluated but no condition on it has been defined. In other words, I would expect it to be written more like: If ValueA And MaskA = 1 Then ' Do stuff. End if I ran the first example and, indeed, it seemed to work OK. So then it seemed that vb.Net can treat such an expression in a special way, assuming that such a line before being evaluated is "0" (False) and then POSSIBLY, not zero AFTER evaluation, making the result "True". Then, based on that assumption, I needed a reverse logic, so that if the condition was False, it would execute rather than when it is True: If Not (ValueA And MaskA) Then ' Do stuff. End if However, that does not work since all that does is essentially take the binary digits and flip them, turning the result into a negative value (a signed integer). So now it seems that the only solution is to set the block up as an If/Else block: If ValueA And MaskA Then ' Do stuff. Else ' Do alternate stuff. End if That should ALWAYS work, I would tend to think. But if my above logic has been perfectly consistent, then the 2nd example in this post, should also work, but with a test for the value "0": If ValueA And MaskA = 0 Then ' Do stuff. End if Alas, it failed, since vb.Net seems fixated on interpreting the result as having to be a Boolean, so my above logic is flawed somewhere. Even though evaluating the result in the Immediate window returns "0", the code does not execute. What IS the vb.Net convention for using bitwise operators in an If-conditional statement? Hopefully the answer to this question can solve the riddle of Global Warming and lead to cures for all diseases! :))

                T Offline
                T Offline
                TnTinMn
                wrote on last edited by
                #9

                Elimate the confusion and set "Option Strict On"; it is off in the default configuration. This will disallow the implied conversion from integer to boolean. see: Visual Studio compiler options, Part 2: Option Strict Also, review Operator Precedence in Visual Basic

                T 1 Reply Last reply
                0
                • D Dave Kreskowiak

                  treddie wrote:

                  After testing, the first example works, the second does not

                  Oh, it works, just not the way to think it does. The result of (ValueA And MaskA) results in an integer value, not True/False. That integer is compared to zero. If the result of the expression is non-zero, True is returned. The Not operator will invert that to False. If the result of the expression is zero, False is returned, then inverted to True by the Not operator. Withouting seeing the values of ValueA and Mask, it's pretty much all we can tell you.

                  A guide to posting questions on CodeProject[^]
                  Dave Kreskowiak

                  T Offline
                  T Offline
                  treddie
                  wrote on last edited by
                  #10

                  The Not operator will invert that to False. But that is not what happens. Here are some actual tests I performed:

                  The value and the mask in these examples are:
                  FileAttributes Value that contains a bit field that indicates whether a resource is a folder or a file.
                  Folder = 8208D, File = 8224D

                  Mask		Bit mask that tests for the presence of a folder (16D).
                  

                  Option Strict is NOT set.
                  _____________________________________________________________________________________________________

                  GOAL: Run code on "True" condition (Resource is a folder):
                  If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                  'Execute code.
                  End If

                  When FileAttributes = 8208D (Folder):
                  	8208D (Folder)    =    		2	0	1	0	H
                  					0010	0000	0001	0000	B
                  	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  	Result			        0000	0000	0001	0000	B    <>	0, ("True"), Code executes as it should.
                  
                  
                  When FileAttributes = 8224D (File):
                  	8224D (File)    =    		2	0	2	0	H
                  					0010	0000	0010	0000	B
                  	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  	Result			        0000	0000	0000	0000	B     =	0, ("False"), Code does not execute.
                  											      This is correct.
                  

                  _____________________________________________________________________________________________________
                  GOAL: Run code on "False" condition (Resource is a file):
                  If Not (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                  'Execute code.
                  End If

                  When FileAttributes = 8208D (Folder):
                  	8208D (Folder)    =    		2	0	1	0	H
                  					0010	0000	0001	0000	B
                  	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  	Result			        0000	0000	0001	0000	B    <> 0, ("True"), Code WOULD  execute, if left as is.
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  				NOT	1111	1111	1110	1111	B    <>	0, ("True"), Code executes when it SHOULD NOT.
                  
                  
                  When FileAttributes = 8224D (File):
                  	8224D (File)    =    		2	0	2	0	H
                  					0010	0000	0010	0000	B
                  	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  	Result			        0000	0000	0000	0000	B    =  0, ("False"), Code does not execute, if left as is.
                                                              \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                  
                  D L 2 Replies Last reply
                  0
                  • T treddie

                    The Not operator will invert that to False. But that is not what happens. Here are some actual tests I performed:

                    The value and the mask in these examples are:
                    FileAttributes Value that contains a bit field that indicates whether a resource is a folder or a file.
                    Folder = 8208D, File = 8224D

                    Mask		Bit mask that tests for the presence of a folder (16D).
                    

                    Option Strict is NOT set.
                    _____________________________________________________________________________________________________

                    GOAL: Run code on "True" condition (Resource is a folder):
                    If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                    'Execute code.
                    End If

                    When FileAttributes = 8208D (Folder):
                    	8208D (Folder)    =    		2	0	1	0	H
                    					0010	0000	0001	0000	B
                    	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    	Result			        0000	0000	0001	0000	B    <>	0, ("True"), Code executes as it should.
                    
                    
                    When FileAttributes = 8224D (File):
                    	8224D (File)    =    		2	0	2	0	H
                    					0010	0000	0010	0000	B
                    	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    	Result			        0000	0000	0000	0000	B     =	0, ("False"), Code does not execute.
                    											      This is correct.
                    

                    _____________________________________________________________________________________________________
                    GOAL: Run code on "False" condition (Resource is a file):
                    If Not (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                    'Execute code.
                    End If

                    When FileAttributes = 8208D (Folder):
                    	8208D (Folder)    =    		2	0	1	0	H
                    					0010	0000	0001	0000	B
                    	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    	Result			        0000	0000	0001	0000	B    <> 0, ("True"), Code WOULD  execute, if left as is.
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    				NOT	1111	1111	1110	1111	B    <>	0, ("True"), Code executes when it SHOULD NOT.
                    
                    
                    When FileAttributes = 8224D (File):
                    	8224D (File)    =    		2	0	2	0	H
                    					0010	0000	0010	0000	B
                    	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    	Result			        0000	0000	0000	0000	B    =  0, ("False"), Code does not execute, if left as is.
                                                                \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                    
                    D Offline
                    D Offline
                    Dave Kreskowiak
                    wrote on last edited by
                    #11

                    OK. You should be testing the value of the bitwise operation against the value of the mask, NOT depending on an implied true or false.

                    A guide to posting questions on CodeProject[^]
                    Dave Kreskowiak

                    1 Reply Last reply
                    0
                    • T treddie

                      The Not operator will invert that to False. But that is not what happens. Here are some actual tests I performed:

                      The value and the mask in these examples are:
                      FileAttributes Value that contains a bit field that indicates whether a resource is a folder or a file.
                      Folder = 8208D, File = 8224D

                      Mask		Bit mask that tests for the presence of a folder (16D).
                      

                      Option Strict is NOT set.
                      _____________________________________________________________________________________________________

                      GOAL: Run code on "True" condition (Resource is a folder):
                      If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                      'Execute code.
                      End If

                      When FileAttributes = 8208D (Folder):
                      	8208D (Folder)    =    		2	0	1	0	H
                      					0010	0000	0001	0000	B
                      	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      	Result			        0000	0000	0001	0000	B    <>	0, ("True"), Code executes as it should.
                      
                      
                      When FileAttributes = 8224D (File):
                      	8224D (File)    =    		2	0	2	0	H
                      					0010	0000	0010	0000	B
                      	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      	Result			        0000	0000	0000	0000	B     =	0, ("False"), Code does not execute.
                      											      This is correct.
                      

                      _____________________________________________________________________________________________________
                      GOAL: Run code on "False" condition (Resource is a file):
                      If Not (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                      'Execute code.
                      End If

                      When FileAttributes = 8208D (Folder):
                      	8208D (Folder)    =    		2	0	1	0	H
                      					0010	0000	0001	0000	B
                      	16D (Mask)        =	AND	0000	0000	0001	0000	B
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      	Result			        0000	0000	0001	0000	B    <> 0, ("True"), Code WOULD  execute, if left as is.
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      				NOT	1111	1111	1110	1111	B    <>	0, ("True"), Code executes when it SHOULD NOT.
                      
                      
                      When FileAttributes = 8224D (File):
                      	8224D (File)    =    		2	0	2	0	H
                      					0010	0000	0010	0000	B
                      	16D (Mask)      =	AND	0000	0000	0001	0000	B
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      	Result			        0000	0000	0000	0000	B    =  0, ("False"), Code does not execute, if left as is.
                                                                  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
                      
                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #12

                      That is the difference between a logical and a bitwise expression. In your expressions you cannot use NOT to invert from non-zero (implied TRUE) to FALSE. I think as Dave suggests you need something like:

                      If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                      ' it is a directory.
                      Else
                      ' it is NOT a directory.
                      End If

                      or even

                      If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY Then
                      ' it is a directory.
                      Else
                      ' it is NOT a directory.
                      End If

                      Use the best guess

                      T 1 Reply Last reply
                      0
                      • L Lost User

                        That is the difference between a logical and a bitwise expression. In your expressions you cannot use NOT to invert from non-zero (implied TRUE) to FALSE. I think as Dave suggests you need something like:

                        If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                        ' it is a directory.
                        Else
                        ' it is NOT a directory.
                        End If

                        or even

                        If (FileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY Then
                        ' it is a directory.
                        Else
                        ' it is NOT a directory.
                        End If

                        Use the best guess

                        T Offline
                        T Offline
                        treddie
                        wrote on last edited by
                        #13

                        That is the conclusion I came to in an earlier post. But I needed to understand why, and now I think I get the behavior. It's kind of like that old saying, "You can prove a positive, but you can't prove a negative." At least not without that extra Else clause thrown in.

                        L 1 Reply Last reply
                        0
                        • T TnTinMn

                          Elimate the confusion and set "Option Strict On"; it is off in the default configuration. This will disallow the implied conversion from integer to boolean. see: Visual Studio compiler options, Part 2: Option Strict Also, review Operator Precedence in Visual Basic

                          T Offline
                          T Offline
                          treddie
                          wrote on last edited by
                          #14

                          Good advice.

                          1 Reply Last reply
                          0
                          • T treddie

                            That is the conclusion I came to in an earlier post. But I needed to understand why, and now I think I get the behavior. It's kind of like that old saying, "You can prove a positive, but you can't prove a negative." At least not without that extra Else clause thrown in.

                            L Offline
                            L Offline
                            Lost User
                            wrote on last edited by
                            #15

                            treddie wrote:

                            It's kind of like that old saying, "You can prove a positive, but you can't prove a negative." At least not without that extra Else clause thrown in.

                            Well that's not quite the issue. The issue is that you are using a bitwise operation whose result will be some number of 1 bits, including zero. If you than apply the NOT operator (which is also a bitwise operator) to that result you will get the bitwise complement. Neither of these is a boolean expression so their results are neither TRUE nor FALSE, they are just some number of bits from 0 to hex FF etc. If the result has any bits set then it is generally assumed to be TRUE in an IF clause; if it has no bits set then it is assumed to be FALSE. But applying the NOT operator to a non-zero result, can still give a non-zero answer. If you want strict boolean tests then you must include a comparison operator in the expression, as I did in the second example of my previous answer.

                            Use the best guess

                            T 1 Reply Last reply
                            0
                            • L Lost User

                              treddie wrote:

                              It's kind of like that old saying, "You can prove a positive, but you can't prove a negative." At least not without that extra Else clause thrown in.

                              Well that's not quite the issue. The issue is that you are using a bitwise operation whose result will be some number of 1 bits, including zero. If you than apply the NOT operator (which is also a bitwise operator) to that result you will get the bitwise complement. Neither of these is a boolean expression so their results are neither TRUE nor FALSE, they are just some number of bits from 0 to hex FF etc. If the result has any bits set then it is generally assumed to be TRUE in an IF clause; if it has no bits set then it is assumed to be FALSE. But applying the NOT operator to a non-zero result, can still give a non-zero answer. If you want strict boolean tests then you must include a comparison operator in the expression, as I did in the second example of my previous answer.

                              Use the best guess

                              T Offline
                              T Offline
                              treddie
                              wrote on last edited by
                              #16

                              Makes total sense.

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups