too many flags (bitewise) - over 80(!!) error results - c#

I have a subsystem of a peripherals hardwares. Each peripheral can return few errors
The sub system indicates each error in a flag so when I call a method to check all the peripheral status it returns me a Uint64 code, which is a sum of all of the error codes
example
error1 = 1;
error2 = 2;
error3 = 4;
......
error7 = 64;
error8 = 128;
error9 = 256;
.......
so if i get a return code of 196 it mean i got error3,error8 and error 7 (4+64+128)
the number of total error can reach more than 50 errors and that's why the return code is Uint64
which the error64 can be a very large number(18446744073709551616), and can have more then 80 error in future reference
Is there a way to implement flag system when are more then 50 flags to check?

I will try to give a mechanism for storing more than 64 errors with a Uint64 Enum.
public enum MyFlag : UInt64
{
control = 1,
error1 = 2,
error2 = 4,
error3 = 8,
//.......
error63 = 9223372036854775808
}
This is the enum. Observe that we reserve the least significant bit for a control bit.
This means we can now have 63*2 = 126 different codes.
The drawback is that instead of the usual check, for instance:
resultFlag & MyFlag.error3
we will need to make a composite check, like:
resultFlag & MyFlag.error3 && resultFlag & MyFlag.control
or:
resultFlag & MyFlag.error3 && resultFlag%2
I hope this helps. Cheers.

you can create enum:
[Flags] enum Errors {error1 =1,error2=2,error3=4, error4=8}
and then when you get answer from your subsystem just do that.
var MyNewError = 11;
Errors DecodedErrors = (Errors)MyNewError;
and then you will get fast list of all errors by converting DecodedErrors to string.
Console.WriteLine(DecodedErrors.ToString());
//output: error1, error2, error4
Combine it with #nestedloop solution and you are in home.

Related

Which logical operations can I use to ignore irrelevant bits when masking?

Context
Let's say that I have a system model which comprises of 8 Boolean variables. Together, they comprise a byte that may expresses the 128 state permutations of my system. Let this byte be stateByte, whereby each bit is one of my variables.
Now, suppose I have some enumerable states, such as:
public enum States
{
READY = 0b_0000_0001
OPERATING = 0b_0100_0000
FAULT = 0b_1000_0000
}
If it were that each of the States were discrete, I could easily determine States currentState = (States)stateByte, however my problem is:
My states are only each dependent on a subset of specific bits, not the entire byte. Specifically, there are some bits that are irrelevant depending on the state. To use pseudo notation, I have the scenario below where x notates an irrelevant bit:
public enum States
{
READY = 0b_0000_0001 // Exactly this permutation
OPERATING = 0b_0100_0000 // Exactly this permutation
FAULT = 0b_1xxx_xxxx // Only bit 7 need be high to determine a fault
}
Question
How can I use logical, bitwise operators (masking) in order to enumerate states from only relevant bits?
Further Context
For those sticklers for detail who would question why I am trying to do this or why I cannot simply use thresholds, please see below the full state table of the hardware I am integrating:
If the flags solution is valid then it would be done like this:
[Flags]
public enum States
{
READY = 0b_0000_0001,
OPERATING = 0b_0100_0000,
FAULT = 0b_1000_0000
}
static void Main(string[] args)
{
var s = (States)5;
var check = s = States.FAULT | States.OPERATING;
}
You could use the binary and operator & to mask values, such as to only include certain bits:
0b_1xxx_xxxx & 0b_1000_0000 = 0b_1000_0000
0b_1xxx_xxxx & (1 << 7) = 0b_1000_0000
0b_1xxx_xxxx & States.Fault = 0b_1000_0000
If you want to access certain bits often you could write an extension method like this:
public static boolean GetBit(this byte bitmask, int index) =>
((bitmask >> index) & 1) != 0;
0b_1xxx_xxxx.GetBit(7) = true
If you want to check multiple bits at once, you can use a pattern that matches all bits you want to check and compare them with another pattern containing all "correct" bits and 0s everywhere else:
0b_x0xx_1000
& 0b_0100_1111 // Only look at bits 0-3 and 6
== 0b_0000_1000 // Check that bit 6 is 0, 3 is 1 and 0-2 are 0
// Other bits are 0 due to the logical and

Defining a bit[] array in C#

currently im working on a solution for a prime-number calculator/checker. The algorythm is already working and verry efficient (0,359 seconds for the first 9012330 primes). Here is a part of the upper region where everything is declared:
const uint anz = 50000000;
uint a = 3, b = 4, c = 3, d = 13, e = 12, f = 13, g = 28, h = 32;
bool[,] prim = new bool[8, anz / 10];
uint max = 3 * (uint)(anz / (Math.Log(anz) - 1.08366));
uint[] p = new uint[max];
Now I wanted to go to the next level and use ulong's instead of uint's to cover a larger area (you can see that already), where i tapped into my problem: the bool-array.
Like everybody should know, bool's have the length of a byte what takes a lot of memory when creating the array... So I'm searching for a more resource-friendly way to do that.
My first idea was a bit-array -> not byte! <- to save the bool's, but haven't figured out how to do that by now. So if someone ever did something like this, I would appreciate any kind of tips and solutions. Thanks in advance :)
You can use BitArray collection:
http://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx
MSDN Description:
Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).
You can (and should) use well tested and well known libraries.
But if you're looking to learn something (as it seems to be the case) you can do it yourself.
Another reason you may want to use a custom bit array is to use the hard drive to store the array, which comes in handy when calculating primes. To do this you'd need to further split addr, for example lowest 3 bits for the mask, next 28 bits for 256MB of in-memory storage, and from there on - a file name for a buffer file.
Yet another reason for custom bit array is to compress the memory use when specifically searching for primes. After all more than half of your bits will be 'false' because the numbers corresponding to them would be even, so in fact you can both speed up your calculation AND reduce memory requirements if you don't even store the even bits. You can do that by changing the way addr is interpreted. Further more you can also exclude numbers divisible by 3 (only 2 out of every 6 numbers has a chance of being prime) thus reducing memory requirements by 60% compared to plain bit array.
Notice the use of shift and logical operators to make the code a bit more efficient.
byte mask = (byte)(1 << (int)(addr & 7)); for example can be written as
byte mask = (byte)(1 << (int)(addr % 8));
and addr >> 3 can be written as addr / 8
Testing shift/logical operators vs division shows 2.6s vs 4.8s in favor of shift/logical for 200000000 operations.
Here's the code:
void Main()
{
var barr = new BitArray(10);
barr[4] = true;
Console.WriteLine("Is it "+barr[4]);
Console.WriteLine("Is it Not "+barr[5]);
}
public class BitArray{
private readonly byte[] _buffer;
public bool this[long addr]{
get{
byte mask = (byte)(1 << (int)(addr & 7));
byte val = _buffer[(int)(addr >> 3)];
bool bit = (val & mask) == mask;
return bit;
}
set{
byte mask = (byte) ((value ? 1:0) << (int)(addr & 7));
int offs = (int)addr >> 3;
_buffer[offs] = (byte)(_buffer[offs] | mask);
}
}
public BitArray(long size){
_buffer = new byte[size/8 + 1]; // define a byte buffer sized to hold 8 bools per byte. The spare +1 is to avoid dealing with rounding.
}
}

Why do enum permissions often have 0, 1, 2, 4 values?

Why are people always using enum values like 0, 1, 2, 4, 8 and not 0, 1, 2, 3, 4?
Has this something to do with bit operations, etc.?
I would really appreciate a small sample snippet on how this is used correctly :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
Because they are powers of two and I can do this:
var permissions = Permissions.Read | Permissions.Write;
And perhaps later...
if( (permissions & Permissions.Write) == Permissions.Write )
{
// we have write access
}
It is a bit field, where each set bit corresponds to some permission (or whatever the enumerated value logically corresponds to). If these were defined as 1, 2, 3, ... you would not be able to use bitwise operators in this fashion and get meaningful results. To delve deeper...
Permissions.Read == 1 == 00000001
Permissions.Write == 2 == 00000010
Permissions.Delete == 4 == 00000100
Notice a pattern here? Now if we take my original example, i.e.,
var permissions = Permissions.Read | Permissions.Write;
Then...
permissions == 00000011
See? Both the Read and Write bits are set, and I can check that independently (Also notice that the Delete bit is not set and therefore this value does not convey permission to delete).
It allows one to store multiple flags in a single field of bits.
If it is still not clear from the other answers, think about it like this:
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
is just a shorter way to write:
public enum Permissions
{
DeleteNoWriteNoReadNo = 0, // None
DeleteNoWriteNoReadYes = 1, // Read
DeleteNoWriteYesReadNo = 2, // Write
DeleteNoWriteYesReadYes = 3, // Read + Write
DeleteYesWriteNoReadNo = 4, // Delete
DeleteYesWriteNoReadYes = 5, // Read + Delete
DeleteYesWriteYesReadNo = 6, // Write + Delete
DeleteYesWriteYesReadYes = 7, // Read + Write + Delete
}
There are eight possibilities but you can represent them as combinations of only four members. If there were sixteen possibilities then you could represent them as combinations of only five members. If there were four billion possibilities then you could represent them as combinations of only 33 members! It is obviously far better to have only 33 members, each (except zero) a power of two, than to try to name four billion items in an enum.
Because these values represent unique bit locations in binary:
1 == binary 00000001
2 == binary 00000010
4 == binary 00000100
etc., so
1 | 2 == binary 00000011
EDIT:
3 == binary 00000011
3 in binary is represented by a value of 1 in both the ones place and the twos place. It is actually the same as the value 1 | 2. So when you are trying to use the binary places as flags to represent some state, 3 isn't usually meaningful (unless there is a logical value that actually is the combination of the two)
For further clarification, you might want to extend your example enum as follows:
[Flags]
public Enum Permissions
{
None = 0, // Binary 0000000
Read = 1, // Binary 0000001
Write = 2, // Binary 0000010
Delete = 4, // Binary 0000100
All = 7, // Binary 0000111
}
Therefore in I have Permissions.All, I also implicitly have Permissions.Read, Permissions.Write, and Permissions.Delete
[Flags]
public Enum Permissions
{
None = 0; //0000000
Read = 1; //0000001
Write = 1<<1; //0000010
Delete = 1<<2; //0000100
Blah1 = 1<<3; //0001000
Blah2 = 1<<4; //0010000
}
I think writing using a binary shift operator << is easier to understand and read, and you don't need to calculate it.
These are used to represent bit flags which allows combinations of enum values. I think it's clearer if you write the values in hex notation
[Flags]
public Enum Permissions
{
None = 0x00,
Read = 0x01,
Write = 0x02,
Delete= 0x04,
Blah1 = 0x08,
Blah2 = 0x10
}
This is really more of a comment, but since that wouldn't support formatting, I just wanted to include a method I've employed for setting up flag enumerations:
[Flags]
public enum FlagTest
{
None = 0,
Read = 1,
Write = Read * 2,
Delete = Write * 2,
ReadWrite = Read|Write
}
I find this approach especially helpful during development in the case where you like to maintain your flags in alphabetical order. If you determine you need to add a new flag value, you can just insert it alphabetically and the only value you have to change is the one it now precedes.
Note, however, that once a solution is published to any production system (especially if the enum is exposed without a tight coupling, such as over a web service), then it is highly advisable against changing any existing value within the enum.
Lot's of good answers to this one… I'll just say.. if you do not like, or cannot easily grasp what the << syntax is trying to express.. I personally prefer an alternative (and dare I say, straightforward enum declaration style)…
typedef NS_OPTIONS(NSUInteger, Align) {
AlignLeft = 00000001,
AlignRight = 00000010,
AlignTop = 00000100,
AlignBottom = 00001000,
AlignTopLeft = 00000101,
AlignTopRight = 00000110,
AlignBottomLeft = 00001001,
AlignBottomRight = 00001010
};
NSLog(#"%ld == %ld", AlignLeft | AlignBottom, AlignBottomLeft);
LOG 513 == 513
So much easier (for myself, at least) to comprehend. Line up the ones… describe the result you desire, get the result you WANT.. No "calculations" necessary.

not being able to convert from FILETIME (windows time) to dateTime ( I get a different date )

Most of the files I read get the right time when using the following method to convert:
// works great most of the time
private static DateTime convertToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME time)
{
long highBits = time.dwHighDateTime;
highBits = highBits << 32;
return DateTime.FromFileTimeUtc(highBits + time.dwLowDateTime);
}
Here I have an example in visual studio to show how this method sometimes does not work for example I will show the actual file in my computer and the debug. So the file that happens to be in my debug is:
"A:\Users\Tono\Documents\Visual Studio 2010\Projects\WpfApplication4\WpfApplication4\obj\x86\Debug\App.g.cs"
And here is the FILETIME that I am trying to convert to DateTime "I need the LastWriteTime by the way"
Here you can see that dwHighDateTime = 30136437 and also that dwLowDateTime = -2138979250 from that file.
And when I run my method plus other techniques I get the following dates:
So so far everything seems to be working great. But why is that that when I browse and look for that specific file in windows I get a different date !? Here is the date that I get when seeing the file's properties:
Why does the dates don't match? What am I doing wrong?
You need to combine the LS and MS values bitwise, not arithmetically.
Try:
ulong high = 30136437;
unchecked
{
int low = -2138979250;
uint uLow = (uint)low;
high = high << 32;
Date dt = DateTime.FromFileTime((long) (high | (ulong)uLow));
}
Or any of the following should work too:
long highBits = time.dwHighDateTime;
highBits = highBits << 32;
return DateTime.FromFileTimeUtc(highBits + (long) (uint) time.dwLowDateTime);
return DateTime.FromFileTimeUtc(highBits | (long) (uint) time.dwLowDateTime);
return DateTime.FromFileTimeUtc(highBits + ((long)low & 0xFFFFFFFF))
return DateTime.FromFileTimeUtc(highBits | ((long)low & 0xFFFFFFFF))
You can get away with adding rather than a bitwise-or if you are sure the values are positive (and have no bits in common). But bitwise-or expresses the intent better.
I'm a bit late to the party, but this has worked reliably for me:
public static class FILETIMEExtensions
{
public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME time)
{
ulong high = (ulong)time.dwHighDateTime;
uint low = (uint)time.dwLowDateTime;
long fileTime = (long)((high << 32) + low);
try
{
return DateTime.FromFileTimeUtc(fileTime);
}
catch
{
return DateTime.FromFileTimeUtc(0xFFFFFFFF);
}
}
}
Note: Don't trust Windows Explorer. Use File.GetLastWriteTimeUtc method, for example, to verify what the file system actually has against what this extension method returns. Explorer has some bugs in it that don't update file times in certain situations. Cheers! :)
Note: To test this, you need to use maximum values. So, assuming dwHighDateTime = dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF, it follows that (long)(((ulong)UInt32.MaxValue << 32) + UInt32.MaxValue) = -1 = 0xFFFFFFFFFFFFFFFF. Unfortunately, the fallacy in the Windows API seems to be that eventually the time needs to be casted to a long value in order to work with it for any useful applications (since most Windows API methods take the file time as a long value), which means once the leading bit is high (1) on dwHighDateTime, the value becomes negative. Lets try with the maximum time not being high. Assuming dwHighDateTime = Int32.MaxValue = 2147483647 = 0x7FFFFFFF and dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF, it follows that (long)(((ulong)Int32.MaxValue << 32) + UInt32.MaxValue) = 0x7FFFFFFFFFFFFFFF.
Note: 0x7FFFFFFFFFFFFFFF is already much larger than DateTime.MaxValue.ToFileTimeUtc() = 2650467743999999999 = 0x24C85A5ED1C04000, rendering numbers that large already useless for any practical applications in .NET.
This is another method that I have seen to convert a FileTime structure to a long (using a coded operator in the struct), which can then easily be converted to DateTime using the DateTime.FromFileTime functions:
public struct FileTime
{
public uint dwLowDateTime;
public uint dwHighDateTime;
public static implicit operator long(FileTime fileTime)
{
long returnedLong;
// Convert 4 high-order bytes to a byte array
byte[] highBytes = BitConverter.GetBytes(fileTime.dwHighDateTime);
// Resize the array to 8 bytes (for a Long)
Array.Resize(ref highBytes, 8);
// Assign high-order bytes to first 4 bytes of Long
returnedLong = BitConverter.ToInt64(highBytes, 0);
// Shift high-order bytes into position
returnedLong = returnedLong << 32;
// Or with low-order bytes
returnedLong = returnedLong | fileTime.dwLowDateTime;
// Return long
return returnedLong;
}
}
I have tried the following and non of them get me the right time:
And I got the method from here
dwLowDateTime and dwHighDateTime should be uint and it looks like they are int. Changing this will most likely fix it though as #Joe pointed out you should still use | instead of +.

How do I check for presence of a bit in C# using AND?

How to I use logical operators to determine if a bit is set, or is bit-shifting the only way?
I found this question that uses bit shifting, but I would think I can just AND out my value.
For some context, I'm reading a value from Active Directory and trying to determine if it a Schema Base Object. I think my problem is a syntax issue, but I'm not sure how to correct it.
foreach (DirectoryEntry schemaObjectToTest in objSchema.Children)
{
var resFlag = schemaObjectToTest.Properties["systemFlags"].Value;
//if bit 10 is set then can't be made confidential.
if (resFlag != null)
{
byte original = Convert.ToByte( resFlag );
byte isFlag_Schema_Base_Object = Convert.ToByte( 2);
var result = original & isFlag_Schema_Base_Object;
if ((result) > 0)
{
//A non zero result indicates that the bit was found
}
}
}
When I look at the debugger:
resFlag is an object{int} and the value is 0x00000010.
isFlag_Schema_Base_Object, is 0x02
resFlag is 0x00000010 which is 16 in decimal, or 10000 in binary. So it seems like you want to test bit 4 (with bit 0 being the least significant bit), despite your comment saying "if bit 10 is set".
If you do need to test bit 4, then isFlag_Schema_Base_Object needs to be initialised to 16, which is 0x10.
Anyway, you are right - you don't need to do bit shifting to see if a bit is set, you can AND the value with a constant that has just that bit set, and see if the result is non-zero.
If the bit is set:
original xxx1xxxx
AND
isFlag_Schema_Base_Object 00010000
-----------------------------------
= 00010000 (non-zero)
But if the bit isn't set:
original xxx0xxxx
AND
isFlag_Schema_Base_Object 00010000
-----------------------------------
= 00000000 (zero)
Having said that, it might be clearer to initialise isFlag_Schema_Base_Object using the value 1<<4, to make it clear that you're testing whether bit 4 is set.
If you know which bit to check and you're dealing with int's you can use BitVector32.
int yourValue = 5;
BitVector32 bv = new BitVector32(yourValue);
int bitPositionToCheck = 3;
int mask = Enumerable.Range(0, bitPositionToCheck).Select(BitVector32.CreateMask).Last();
bool isSet = bv[mask];
Using bitshifting is probably cleaner than using CreateMask. But it's there :)

Categories