C# Bitwise Operators?
-
Okay, im really a bit baffled here. I am putting together some code from two different samples on here, to make a WinZip-compatible CRC32 ColumnHandler for explorer, to make my work go easier. The code uses a bit-field for a WinAPI call. Now, i was always taught that if you have a bit-field, and you want to set one of the flags in it on, then you OR them together, and if you want to check if a field has a particular flag on, then you AND them. So i tried this, and it crashed my devenv process. So, just for kicks, i tried reversing them, and low-and-behold, it works! C#:OR apparently is equal to the rest of the world's, AND. C#:AND apparently is equal to the rest of the world's, OR. at least bitwise. Did Microsoft actually get so bold as to decide to rewrite the laws of logic? :omg: This is absolutely bizarre.
-
Okay, im really a bit baffled here. I am putting together some code from two different samples on here, to make a WinZip-compatible CRC32 ColumnHandler for explorer, to make my work go easier. The code uses a bit-field for a WinAPI call. Now, i was always taught that if you have a bit-field, and you want to set one of the flags in it on, then you OR them together, and if you want to check if a field has a particular flag on, then you AND them. So i tried this, and it crashed my devenv process. So, just for kicks, i tried reversing them, and low-and-behold, it works! C#:OR apparently is equal to the rest of the world's, AND. C#:AND apparently is equal to the rest of the world's, OR. at least bitwise. Did Microsoft actually get so bold as to decide to rewrite the laws of logic? :omg: This is absolutely bizarre.
Whosit wrote: This is absolutely bizarre. It certainly is. If I were to take a guess I would say there is some greater problem somewhere else in your code, because bitwise-or and bitwise-and work the same as they do in C/C++. James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation
-
Whosit wrote: This is absolutely bizarre. It certainly is. If I were to take a guess I would say there is some greater problem somewhere else in your code, because bitwise-or and bitwise-and work the same as they do in C/C++. James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation
Well, i dont think so, but its not mostly my code. To make my CRC32 ColumnHandler i took the ColumnH code from the first project below, and just dropped in the CRC32 class from the second one in place of the MD5 code. The only other changes i made (which is where i had the & vs. | problem) Is below... http://www.codeproject.com/csharp/ColumnHandler.asp http://www.codeproject.com/csharp/crc32\_dotnet.asp In the implementation of GetColumnInfo i changed the column title and description and then:
psci.fmt=LVCFMT.RIGHT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR;
topsci.fmt=LVCFMT.LEFT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW;
The last line setting csFlags is where i had problems. When i tried to use the OR (|) it consistently hung. But when i use the AND (&) it works just beautifully with the right results and all. Then what threw me off even more was a line (unchanged) in GetItemData which reads:if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory)
Where the original author is checking the flag with an OR. This is all quite backwards from what i know of bit-wise logic. Any explanations or ideas why this is? -
Well, i dont think so, but its not mostly my code. To make my CRC32 ColumnHandler i took the ColumnH code from the first project below, and just dropped in the CRC32 class from the second one in place of the MD5 code. The only other changes i made (which is where i had the & vs. | problem) Is below... http://www.codeproject.com/csharp/ColumnHandler.asp http://www.codeproject.com/csharp/crc32\_dotnet.asp In the implementation of GetColumnInfo i changed the column title and description and then:
psci.fmt=LVCFMT.RIGHT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR;
topsci.fmt=LVCFMT.LEFT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW;
The last line setting csFlags is where i had problems. When i tried to use the OR (|) it consistently hung. But when i use the AND (&) it works just beautifully with the right results and all. Then what threw me off even more was a line (unchanged) in GetItemData which reads:if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory)
Where the original author is checking the flag with an OR. This is all quite backwards from what i know of bit-wise logic. Any explanations or ideas why this is?whosit wrote: Any explanations or ideas why this is? I can't think of any reasons, but a quick test shows that what we know of as bitwise logic is what C# uses.
[Flags()]
public enum Enum
{
A = 1,
B = 2,
C = 4,
D = A | B,
E = 8,
F = 64
}[STAThread]
static void Main(string[] args)
{
Enum e = Enum.A;
Console.WriteLine("e = {0}", e);e = Enum.A | Enum.C; Console.WriteLine("e should equal (A): e = {0}", e); if( (e & Enum.A) == Enum.A ) Console.WriteLine("Enum.A is set"); else Console.WriteLine("Enum.A isn't set"); e = (e | Enum.B); Console.WriteLine("e should (A, B, C) or (D, C): e = {0}", e); if( (e & Enum.C) == Enum.C ) Console.WriteLine("Enum.C is set"); if( (e & Enum.B) == Enum.B ) Console.WriteLine("Enum.B is set"); if( (e & Enum.A) == Enum.A) Console.WriteLine("Enum.A is set"); e = e | Enum.E; if( (e & Enum.E) == Enum.E) Console.WriteLine("Enum.E is set - correct usage"); if( (e | Enum.E) == Enum.E) Console.WriteLine("Enum.E is set - incorrect usage"); e = e & (~Enum.E); Console.WriteLine("e should be (A, B, C) or (D, C)...e was unset: e = {0}", e); Console.ReadLine();
}
The output should be:
e = A
e should equal (A): e = A, C
Enum.A is set
e should (A, B, C) or (D, C): e = D, C
Enum.C is set
Enum.B is set
Enum.A is set
Enum.E is set - correct usage
e should be (A, B, C) or (D, C)...E was unset: e = D, CNow as to the next part... whosit wrote: Then what threw me off even more was a line (unchanged) in GetItemData which reads: if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory) Where the original author is checking the flag with an OR. The code above would work, so long as pscd.dwFileAttributes had either no flags set or just the FileAttributes.Directory flag set, in which case the bitwise-or effectively does nothing and the check continues to work. Doing a quick test if I change the | to the proper & it still works as expected, and taking a look at some directories I can't find any that don't report to contain some read-only files, even dirs with no files in them. Trying to change that (by unchecking readonly in the dir properties box) has no effect. James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation
-
whosit wrote: Any explanations or ideas why this is? I can't think of any reasons, but a quick test shows that what we know of as bitwise logic is what C# uses.
[Flags()]
public enum Enum
{
A = 1,
B = 2,
C = 4,
D = A | B,
E = 8,
F = 64
}[STAThread]
static void Main(string[] args)
{
Enum e = Enum.A;
Console.WriteLine("e = {0}", e);e = Enum.A | Enum.C; Console.WriteLine("e should equal (A): e = {0}", e); if( (e & Enum.A) == Enum.A ) Console.WriteLine("Enum.A is set"); else Console.WriteLine("Enum.A isn't set"); e = (e | Enum.B); Console.WriteLine("e should (A, B, C) or (D, C): e = {0}", e); if( (e & Enum.C) == Enum.C ) Console.WriteLine("Enum.C is set"); if( (e & Enum.B) == Enum.B ) Console.WriteLine("Enum.B is set"); if( (e & Enum.A) == Enum.A) Console.WriteLine("Enum.A is set"); e = e | Enum.E; if( (e & Enum.E) == Enum.E) Console.WriteLine("Enum.E is set - correct usage"); if( (e | Enum.E) == Enum.E) Console.WriteLine("Enum.E is set - incorrect usage"); e = e & (~Enum.E); Console.WriteLine("e should be (A, B, C) or (D, C)...e was unset: e = {0}", e); Console.ReadLine();
}
The output should be:
e = A
e should equal (A): e = A, C
Enum.A is set
e should (A, B, C) or (D, C): e = D, C
Enum.C is set
Enum.B is set
Enum.A is set
Enum.E is set - correct usage
e should be (A, B, C) or (D, C)...E was unset: e = D, CNow as to the next part... whosit wrote: Then what threw me off even more was a line (unchanged) in GetItemData which reads: if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory) Where the original author is checking the flag with an OR. The code above would work, so long as pscd.dwFileAttributes had either no flags set or just the FileAttributes.Directory flag set, in which case the bitwise-or effectively does nothing and the check continues to work. Doing a quick test if I change the | to the proper & it still works as expected, and taking a look at some directories I can't find any that don't report to contain some read-only files, even dirs with no files in them. Trying to change that (by unchecking readonly in the dir properties box) has no effect. James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation
-
Well, i dont think so, but its not mostly my code. To make my CRC32 ColumnHandler i took the ColumnH code from the first project below, and just dropped in the CRC32 class from the second one in place of the MD5 code. The only other changes i made (which is where i had the & vs. | problem) Is below... http://www.codeproject.com/csharp/ColumnHandler.asp http://www.codeproject.com/csharp/crc32\_dotnet.asp In the implementation of GetColumnInfo i changed the column title and description and then:
psci.fmt=LVCFMT.RIGHT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR;
topsci.fmt=LVCFMT.LEFT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW;
The last line setting csFlags is where i had problems. When i tried to use the OR (|) it consistently hung. But when i use the AND (&) it works just beautifully with the right results and all. Then what threw me off even more was a line (unchanged) in GetItemData which reads:if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory)
Where the original author is checking the flag with an OR. This is all quite backwards from what i know of bit-wise logic. Any explanations or ideas why this is?whosit wrote: if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory) I played around a bit more with the sample and indeed the code above doesn't work like the author intended, but because he wrote exception-safe code you never know it. I through in some System.Diagnositc.Trace.WriteLine calls through out the function, the first was in the if statement where I told it to print the FileAttributes of the item that caused it to trigger the return. Interesting, as I thought only those that are have Directory get printed. Then I added some code in the exception handlers to print out the exceptions and the FileAttributes of the item that had the exception. Each of the exceptions was
Access to the path "C:\path" is denied.
and the FileAttributes was Directory and ReadOnly or Directory and System. whosit wrote: psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW; As to why you had to use & for it to work, I assume it deals with the stuff above. That is my next thing to try :) James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation -
whosit wrote: if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory) I played around a bit more with the sample and indeed the code above doesn't work like the author intended, but because he wrote exception-safe code you never know it. I through in some System.Diagnositc.Trace.WriteLine calls through out the function, the first was in the if statement where I told it to print the FileAttributes of the item that caused it to trigger the return. Interesting, as I thought only those that are have Directory get printed. Then I added some code in the exception handlers to print out the exceptions and the FileAttributes of the item that had the exception. Each of the exceptions was
Access to the path "C:\path" is denied.
and the FileAttributes was Directory and ReadOnly or Directory and System. whosit wrote: psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW; As to why you had to use & for it to work, I assume it deals with the stuff above. That is my next thing to try :) James "It is self repeating, of unknown pattern" Data - Star Trek: The Next Generation -
Well, i dont think so, but its not mostly my code. To make my CRC32 ColumnHandler i took the ColumnH code from the first project below, and just dropped in the CRC32 class from the second one in place of the MD5 code. The only other changes i made (which is where i had the & vs. | problem) Is below... http://www.codeproject.com/csharp/ColumnHandler.asp http://www.codeproject.com/csharp/crc32\_dotnet.asp In the implementation of GetColumnInfo i changed the column title and description and then:
psci.fmt=LVCFMT.RIGHT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR;
topsci.fmt=LVCFMT.LEFT; psci.cChars=40; psci.csFlags=SHCOLSTATE.TYPE_STR & SHCOLSTATE.ONBYDEFAULT & SHCOLSTATE.SLOW;
The last line setting csFlags is where i had problems. When i tried to use the OR (|) it consistently hung. But when i use the AND (&) it works just beautifully with the right results and all. Then what threw me off even more was a line (unchanged) in GetItemData which reads:if(((FileAttributes)pscd.dwFileAttributes|FileAttributes.Directory)==FileAttributes.Directory)
Where the original author is checking the flag with an OR. This is all quite backwards from what i know of bit-wise logic. Any explanations or ideas why this is?bitwise operators work just fine in c# 1 | 1 gives 1 0 | 1 gives 1 1 | 0 gives 1 0 | 0 gives 0 just as it should 1 & 1 gives 1 0 & 1 gives 0 1 & 0 gives 0 0 & 0 gives 0 just as it should to .. //Roger