Check bit is on in elegant way [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
In order to check hihest bit is on I use code:
byte data = 0x88 ;
bool is_on= ((data & 0x80) == 0x80);
How to do this in more elegant and C# way ?

public static bool Get(byte b, int position)
{
if (position > 7)
throw new ArgumentException();
return ((b & (byte)(1 << position)) != 0);
}

Since you're checking a bit, the only thing I might do is write out the literal so you can see the individual bits, like this:
int mask = 0b1000_0000;
byte data = 0x88 ;
bool is_on= ((data & mask) == mask);
I might further abstract this as a method:
public static bool MatchesMask(this int data, int mask)
{
return (data&mask)==mask;
}
So I could call it like this:
int mask = 0b1000_0000;
byte data = 0x88 ;
bool is_on = data.MatchesMask(mask);

If you are dealing with bit setting and getting consider some auxiliary classes to help you. Look at the Flag structure below
Usage
You initialize a Flag with a mask Flag flag = 0x20, or set a specific bit Flag flag = Flag.Bit(5).
You poll a bit with flag.Get(value) and you set a bit with value = flag.Set(value); to set to 1, and value = flag.Set(value, false); to set it 0.
Test Output
10110011 & 00100000 = True
10010011 & 00100000 = False
Code
public struct Flag
{
readonly byte mask;
public Flag(byte mask)
{
this.mask=mask;
}
public byte Mask => this.mask;
public static Flag Bit(int position)
=> new Flag((byte)(1<<position));
public static implicit operator byte(Flag bit) => bit.mask;
public static implicit operator Flag(byte mask) => new Flag(mask);
public bool Get(byte value) => (value & mask)!=0;
public byte Set(byte value, bool bit = true)
{
if (bit)
{
return (byte)(value | mask);
}
else
{
return (byte)(value & ~mask);
}
}
}
static class Program
{
public static string Bin(this byte data)
=> Convert.ToString(data, 2).PadLeft(8, '0');
static void Main(string[] args)
{
byte value = 0xB3;
Flag flag = 0x20;
// or alernativly
// var flag = Flag.Bit(6); // mask = 0b0010000
Console.WriteLine($"{Bin(value)} & {Bin(flag.Mask)} = {flag.Get(value)}");
// not set the bit to 0
value = flag.Set(value, false);
Console.WriteLine($"{Bin(value)} & {Bin(flag.Mask)} = {flag.Get(value)}");
}
}
References
Set a specific bit in an int

Related

Best possible way to Bitwise backwards

I figured out how to pack my bits being a ushort 16bits, my enums are 1 - 13 so they should all fit. Problem is I know I can unpack in a faster fashion then what I was doing and quite shamefully I didn't want to post my horrid code. Any insight would be appreciative. My Push isn't a string it pushes to a byte array so string would be broken down into individual bytes. My ushort is broken down into 2 bytes a float is broken down into 4 bytes etc etc. Here is an image of what I am trying to accomplish..
Revised Code Statements 11/27/2018 11:47pm
Enums.cs
public enum PacketFlags
{
None = 0x1,
Nat = 0x2,
Hb = 0x4,
Dat = 0x8,
Dscvr = 0x16,
Status = 0x20,
Conn = 0x40,
Finn = 0x80,
ReliableOrdered = 0x100,
Sequenced = 0x200,
NotFragged = 0x400,
Frag = 0x800,
Fragout = 0x1000,
}
Methods In Question
public void WriteHeader()
{
Count = Ptr;
var flag = Fragmented | Proto | Flag;
var field = (ushort)flag;
Ptr = 0;
Push(field);
Push(_id);
}
public void ReadHeader()
{
Ptr = 0;
var header = PullUShort();
var flags = (PacketFlags)header;
SetFlag(flags);
SetProto(flags);
SetFrag(flags);
_id = PullUShort();
}
private void SetFlag(PacketFlags flags)
{
//Set Flag
if((flags & PacketFlags.None) != 0)
{
Flag = PacketFlags.None;
}
if ((flags & PacketFlags.Nat) != 0)
{
Flag = PacketFlags.Nat;
}
if ((flags & PacketFlags.Hb) != 0)
{
Flag = PacketFlags.Hb;
}
if ((flags & PacketFlags.Dat) != 0)
{
Flag = PacketFlags.Dat;
}
if ((flags & PacketFlags.Dscvr) != 0)
{
Flag = PacketFlags.Dscvr;
}
if ((flags & PacketFlags.Status) != 0)
{
Flag = PacketFlags.Status;
}
if ((flags & PacketFlags.Conn) != 0)
{
Flag = PacketFlags.Conn;
}
if ((flags & PacketFlags.Finn) != 0)
{
Flag = PacketFlags.Finn;
}
}
private void SetProto(PacketFlags flags)
{
if ((flags & PacketFlags.ReliableOrdered) != 0)
{
Proto = PacketFlags.ReliableOrdered;
}
if ((flags & PacketFlags.Sequenced) != 0)
{
Flag = PacketFlags.Sequenced;
}
}
private void SetFrag(PacketFlags flags)
{
if ((flags & PacketFlags.NotFragged) != 0)
{
Flag = PacketFlags.NotFragged;
}
if ((flags & PacketFlags.Frag) != 0)
{
Flag = PacketFlags.Frag;
}
if ((flags & PacketFlags.Fragout) != 0)
{
Flag = PacketFlags.Fragout;
}
}
Please note I am on .Net 3.5 and this is for a networking solution. Enum.HasValue uses reflection if the application is processing 40k + packets a second and running that method compaired to a bitwise operation its slow. I am not looking for easy I would like performance.
You're trying to specify your flags using bit positions. Its easier if you just use the values at those bits.
[Flags]
public enum PacketFlags : ushort
{
None = 0x01, // this is the same as 1 << 1 = 1
Nat = 0x02, // this is the same as 1 << 2 = 2
Hb = 0x04, // this is the same as 1 << 3 = 4
Dat = 0x08,
Dscvr = 0x10,
Status = 0x20, // this is the same as 1 << 6 = 32
Conn = 0x40,
Finn = 0x80,
}
First, 'none' is typically assigned zero, but that aside, let's assume your flags will always have a bit set, even if no flags are set.
Two, I specified the flag values in hexadecimal, but this isn't necessary. You can use simple base-10 numbers if you prefer.
Three, all the [Flags] attribute does is change what happens when you format your enum to a string. Go ahead and try it. OR some flags together, then call .ToString() on it. Then remove the attribute, and notice the difference. It's handy, but doesn't do anything terribly important.
Now, to your question:
Packing is as simple as bitwise-ORing them together:
var flag = PacketFlags.Nat | PacketFlags.Hb;
You can now cast this to a ushort, when you want the number representation of your flags:
var imaNumber = (ushort)flag; // equals 0x06.
You can see the [Flags] attribute in action:
var inEnglish = flag.ToString(); // contains: "Nat, Hb"
Unpacking is as simple as casting the ushort value to PacketFlags:
var unpacked = (PacketFlags)imaNumber;
You can then check if a particular flag is set using Enum.HasFlags.
This answer is meant to get you started in the right direction. I can amend it as necessary in response to feedback. See where you can take it first.

How to emulate statically the C bitfields in c#?

I have to define a communication protocol and I want to use a bitfield to store some logic values.
I'm working on the both systems: the sender: a device and a .Net software as receiver.
On the firmware side, I defined as usually a bitfield struct like:
struct __attribute__((__packed__)) BitsField
{
// Logic values
uint8_t vesselPresenceSw: 1;
uint8_t drawerPresenceSw: 1;
uint8_t pumpState: 1;
uint8_t waterValveState: 1;
uint8_t steamValveState: 1;
uint8_t motorDriverState: 1;
// Unused
uint8_t unused_0: 1;
uint8_t unused_1: 1;
};
How I can define a same structure on the software side that support a bytes deserialization to build the struct itself?
I'm afraid there is no direct C# equivalent to C-style bitfield structs.
C# is capable, to a limited extent, of approximating C-style unions by using FieldOffset attributes. These explicit layout attributes allow you to specify exact and potentially overlapping field offsets. Unfortunately, that doesn't even get you halfway there: the offsets must be specified in bytes rather than bits, and you cannot enforce a specific width when reading or writing overlapping fields.
The closest C# comes to natively supporting bitfields is probably flag-based enum types. You may find this sufficient, provided you don't need more than 64 bits. Start by declaring an enum based on the smallest unsigned type that will fit all your flags:
[Flags]
public enum BitFields : byte {
None = 0,
VesselPresenceSw = 1 << 0,
DrawerPresenceSw = 1 << 1,
PumpState = 1 << 2,
WaterValveState = 1 << 3,
SteamValveState = 1 << 4,
MotorDriverState = 1 << 5
}
The named items can have any value assigned to them that fits within the underlying type (byte in this case), so one item could represent multiple bits if you wanted it to. Note that if you want to interop directly with a C-style bitfield, your first value should start at the most significant bit rather than the least.
To use your flags, just declare a variable or field of your new type and perform whatever bitwise operations you need:
BitFields bits = BitFields.None;
bits |= BitFields.VesselPresenceSw | BitFields.PumpState;
bits &= ~BitFields.VesselPresenceSw;
// etc.
On the upside, enums declared with [Flags] are nicely formatted when displayed in the debugger or converted to strings. For example, if you were to print the expression BitFields.VesselPresenceSw | BitFields.PumpState, you would get the text DrawerPresenceSw, PumpState.
There is a caveat: the storage for an enum will accept any value that fits within the underlying type. It would be perfectly legal to write:
BitFields badBits = (BitFields)0xFF;
This sets all 8 bits of the byte-sized enumeration, but our named values only cover 6 bits. Depending on your requirements, you may want to declare a constant that encompasses only the 'legal' flags, which you could & against.
If you need anything richer than that, there is a framework-level 'bitfield' data structure called BitArray. However, BitArray is a reference type that uses a managed int[] for storage. It's not going to help you if want a struct that you could use for interop purposes or any kind of memory mapping.
Please see an example,
C code,
struct example_bit_field
{
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char two_bits : 2;
unsigned char four_bits : 4;
}
and C# equivalent,
[BitFieldNumberOfBitsAttribute(8)]
struct ExampleBitField : IBitField
{
[BitFieldInfo(0, 1)]
public bool Bit1 { get; set; }
[BitFieldInfo(1, 1)]
public byte Bit2 { get; set; }
[BitFieldInfo(2, 2)]
public byte TwoBits { get; set; }
[BitFieldInfo(4, 4)]
public byte FourBits { get; set; }
}
Source :- https://www.codeproject.com/Articles/1095576/Bit-Field-in-Csharp-using-struct
You can try mimic such a struct. It seems, that you want to use it in the interop (say, C routine exchange data with C# program). Since you have logic values, let expose them as bool:
using System.Runtime.InteropServices;
...
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyBitsField {
private Byte m_Data; // We actually store Byte
public MyBitsField(Byte data) {
m_Data = data;
}
private bool GetBit(int index) {
return (m_Data & (1 << index)) != 0;
}
private void SetBit(int index, bool value) {
byte v = (byte)(1 << index);
if (value)
m_Data |= v;
else
m_Data = (byte) ((m_Data | v) ^ v);
}
public bool vesselPresenceSw {
get { return GetBit(0); }
set { SetBit(0, value); }
}
...
public bool motorDriverState {
get { return GetBit(5); }
set { SetBit(5, value); }
}
}
Usage:
var itemToSend = new MyBitsField() {
vesselPresenceSw = false,
motorDriverState = true,
};
In the meantime, I had a similar idea #Dmitry.
I found the following solution using FieldOffset attribute.
Working well without additional code. I think it's acceptable.
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct LiveDataBitField
{
// Where the values are effectively stored
public byte WholeField { get; private set; }
public bool VesselPresenceSw
{
get => (WholeField & 0x1) > 0;
set
{
if (value)
{
WholeField |= 1;
}
else
{
WholeField &= 0xfE;
}
}
}
public bool DrawerPresenceSw
{
get => (WholeField & 0x2) >> 1 > 0;
set
{
if (value)
{
WholeField |= (1 << 1);
}
else
{
WholeField &= 0xFD;
}
}
}
public bool PumpState
{
get => (WholeField & 0x4) >> 2 > 0;
set
{
if (value)
{
WholeField |= (1 << 2);
}
else
{
WholeField &= 0xFB;
}
}
}
public bool WaterValveState
{
get => (WholeField & 0x8) >> 3 > 0;
set
{
if (value)
{
WholeField |= (1 << 3);
}
else
{
WholeField &= 0xF7;
}
}
}
public bool SteamValveState
{
get => (WholeField & 0x10) >> 4 > 0;
set
{
if (value)
{
WholeField |= (1 << 4);
}
else
{
WholeField &= 0xEF;
}
}
}
public bool MotorDriverState
{
get => (WholeField & 0x20) >> 5 > 0;
set
{
if (value)
{
WholeField |= (1 << 5);
}
else
{
WholeField &= 0xDF;
}
}
}
}
To deserialize a byte array to struct you can use:
public static object ReadStruct(byte[] data, Type type)
{
var pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
var obj = Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), type);
pinnedPacket.Free();
return obj;
}

Byte conversion from 32 bit to 8 bit

hi this I want to send this hex vales but i am getting error.. I am send byte values ,** my error.. constant vales cannot be converted to byte.**
class constant(){
public const byte MESSAGE_START = 0x1020; // command hex
}
public override IEnumerable<byte> ToBytes()
{
yield return constant.MESSAGE_START ;
}
HI, there is another twist i am facing, though with your help I passed the hex value, I should decimal equivalent when i pass through the below method, but value I get is 16.
protected override void TransmitCommand(Device device, Command command)
{
int count = 0;
foreach (var b in command.ToBytes())
transmitBuffer[count++] = b; // values i get is 16 but not decimal values 4128
}
As I said in the comment, the value MESSAGE_START is a short not a byte. Try this
class constant() {
public const short MESSAGE_START = 0x1020; // command hex
}
public override IEnumerable<byte> ToBytes()
{
yield return (byte) (constant.MESSAGE_START >> 8);
yield return (byte) (constant.MESSAGE_START & 0xff);
}
The above code assumes that the byte representation of the value is in network byte order (most significant byte first). For LSB do
public override IEnumerable<byte> ToBytes()
{
yield return (byte) (constant.MESSAGE_START & 0xFF);
yield return (byte) (constant.MESSAGE_START >> 8);
}

BinaryWriterWith7BitEncoding & BinaryReaderWith7BitEncoding

Mr. Ayende wrote in his latest blog post about an implementation of a queue. In the post he's using two magical files: BinaryWriterWith7BitEncoding & BinaryReaderWith7BitEncoding
BinaryWriterWith7BitEncoding can write both int and long? using the following method signatures: void WriteBitEncodedNullableInt64(long? value) & void Write7BitEncodedInt(int value)
and
BinaryReaderWith7BitEncoding can read the values written using the following method signatures: long? ReadBitEncodedNullableInt64() and int Read7BitEncodedInt()
So far I've only managed to find a way to read the 7BitEncodedInt:
protected int Read7BitEncodedInt()
{
int value = 0;
int byteval;
int shift = 0;
while(((byteval = ReadByte()) & 0x80) != 0)
{
value |= ((byteval & 0x7F) << shift);
shift += 7;
}
return (value | (byteval << shift));
}
I'm not too good with byte shifting - does anybody know how to read and write the 7BitEncoded long? and write the int ?
Here's something like the write:
static void Write7BitEncodedInt32(Stream dest, int value)
{
Write7BitEncodedUInt32(dest, (uint) value);
}
static void Write7BitEncodedUInt32(Stream dest, uint value)
{
if(value < 128) { dest.WriteByte((byte)value); return;}
while(value != 0)
{
byte b = (byte) (value & 0x7F);
value >>= 7; // since uint, we'll eventually run out of 1s
if (value != 0) b |= 0x80; // and there's more
dest.WriteByte(b);
}
}

Gray code in .NET

Is there a built in Gray code datatype anywhere in the .NET framework? Or conversion utility between Gray and binary? I could do it myself, but if the wheel has already been invented...
Use this trick.
/*
The purpose of this function is to convert an unsigned
binary number to reflected binary Gray code.
*/
unsigned short binaryToGray(unsigned short num)
{
return (num>>1) ^ num;
}
A tricky Trick: for up to 2^n bits, you can convert Gray to binary by
performing (2^n) - 1 binary-to Gray conversions. All you need is the
function above and a 'for' loop.
/*
The purpose of this function is to convert a reflected binary
Gray code number to a binary number.
*/
unsigned short grayToBinary(unsigned short num)
{
unsigned short temp = num ^ (num>>8);
temp ^= (temp>>4);
temp ^= (temp>>2);
temp ^= (temp>>1);
return temp;
}
Here is a C# implementation that assumes you only want to do this on non-negative 32-bit integers:
static uint BinaryToGray(uint num)
{
return (num>>1) ^ num;
}
You might also like to read this blog post which provides methods for conversions in both directions, though the author chose to represent the code as an array of int containing either one or zero at each position. Personally I would think a BitArray might be a better choice.
Perhaps this collection of methods is useful
based on BitArray
both directions
int or just n Bits
just enjoy.
public static class GrayCode
{
public static byte BinaryToByte(BitArray binary)
{
if (binary.Length > 8)
throw new ArgumentException("bitarray too long for byte");
var array = new byte[1];
binary.CopyTo(array, 0);
return array[0];
}
public static int BinaryToInt(BitArray binary)
{
if (binary.Length > 32)
throw new ArgumentException("bitarray too long for int");
var array = new int[1];
binary.CopyTo(array, 0);
return array[0];
}
public static BitArray BinaryToGray(BitArray binary)
{
var len = binary.Length;
var gray = new BitArray(len);
gray[len - 1] = binary[len - 1]; // copy high-order bit
for (var i = len - 2; i >= 0; --i)
{
// remaining bits
gray[i] = binary[i] ^ binary[i + 1];
}
return gray;
}
public static BitArray GrayToBinary(BitArray gray)
{
var len = gray.Length;
var binary = new BitArray(len);
binary[len - 1] = gray[len - 1]; // copy high-order bit
for (var i = len - 2; i >= 0; --i)
{
// remaining bits
binary[i] = !gray[i] ^ !binary[i + 1];
}
return binary;
}
public static BitArray ByteToGray(byte value)
{
var bits = new BitArray(new[] { value });
return BinaryToGray(bits);
}
public static BitArray IntToGray(int value)
{
var bits = new BitArray(new[] { value });
return BinaryToGray(bits);
}
public static byte GrayToByte(BitArray gray)
{
var binary = GrayToBinary(gray);
return BinaryToByte(binary);
}
public static int GrayToInt(BitArray gray)
{
var binary = GrayToBinary(gray);
return BinaryToInt(binary);
}
/// <summary>
/// Returns the bits as string of '0' and '1' (LSB is right)
/// </summary>
/// <param name="bits"></param>
/// <returns></returns>
public static string AsString(this BitArray bits)
{
var sb = new StringBuilder(bits.Length);
for (var i = bits.Length - 1; i >= 0; i--)
{
sb.Append(bits[i] ? "1" : "0");
}
return sb.ToString();
}
public static IEnumerable<bool> Bits(this BitArray bits)
{
return bits.Cast<bool>();
}
public static bool[] AsBoolArr(this BitArray bits, int count)
{
return bits.Bits().Take(count).ToArray();
}
}
There is nothing built-in as far as Gray code in .NET.
Graphical Explanation about Gray code conversion - this can help a little

Categories