Hey I want to write a struct like the XNA Color struct or the SurfaceFormat.Bgra4444 struct that holds 2 nibbles in a 8 bit byte.
This is what I have so far...
/// <summary>
/// Packed byte containing two 4bit values
/// </summary>
public struct Nibble2 : IEquatable<Nibble2>
{
private byte packedValue;
public byte X
{
get { return 0; }
set { }
}
public byte Y
{
get { return 0; }
set { }
}
/// <summary>
/// Creates an instance of this object.
/// </summary>
/// <param name="x">Initial value for the x component.</param>
/// <param name="y">Initial value for the y component.</param>
public Nibble2(float x, float y)
{
packedValue = 0;
}
/// <summary>
/// Creates an instance of this object.
/// </summary>
/// <param name="vector">Input value for both components.</param>
public Nibble2(Vector2 vector)
{
packedValue = 0;
}
public static bool operator ==(Nibble2 a, Nibble2 b) { return a.packedValue == b.packedValue; }
public static bool operator !=(Nibble2 a, Nibble2 b) { return a.packedValue != b.packedValue; }
public override string ToString()
{ return packedValue.ToString("X : " + X + " Y : " + Y, CultureInfo.InvariantCulture); }
public override int GetHashCode()
{return packedValue;}
public override bool Equals(object obj)
{
if (obj is Nibble2)
return Equals((Nibble2)obj);
return false;
}
public bool Equals(Nibble2 other)
{return packedValue == other.packedValue;}
}
As you can see my propertys and constructors are not implimented. As this is the part I am having trouble with.
Thanks for any help you can provide.
Basically, you just need to keep in mind what is the high and low nibbles. The low nibble can be obtained just by masking with binary 1111 (decimal 15). The high nibble can be obtained (since byte is unsigned) by right-shifting by 4. The rest is just bit-math.
// assume x is the low nibble
public byte X
{
get { return (byte)(packedValue & 15); }
set { packedValue = (packedValue & 240) | (value & 15); }
}
// assume y is the high nibble
public byte Y
{
get { return (byte) (packedValue >> 4); }
set { packedValue = (value << 4) | (packedValue & 15); }
}
I can't, however, help you with:
public Nibble2(float x, float y)
{
packedValue = 0;
}
because that is 64 bits, and you want to fit it into 8. You'd need to be a lot more specific about what you want to do with those values.
Consider the following byte value:
10101100
To read the high bits of a byte, you should shift the bytes to the right:
10101100 (original)
01010110 (shifted one bit)
00101011
00010101
00001010 (shifted four bits)
You can shift bytes by using return (byte)(packedValue >> 4);
To read just the low bits, you simply eliminate the top bits using an AND opertation:
10101100
00001111 AND
--------
00001100
You can perform this AND operation on a value by using return (byte)(packedValue & 0xf);
Setting these values can be performed by clearing the target nibble and then simply adding the input value (shifted left if setting the high nibble):
packedValue = (byte)((packedValue & 0xf0) + (lowNibble & 0xf));
packedValue = (byte)((packedValue & 0xf) + (highNibble << 4));
if you AND the input value with byte filled like this 00001111 which is 15 in dec. You keep the part that you want to save. Then you'll have to left shift the left part of your Nibble2 with 4 bytes to store in the packedValue byte.
private byte x = 0;
private byte y = 0;
public byte X
{
get { return x; }
set { x = value}
}
public byte Y
{
get { return y; }
set { y = value }
}
private byte packedValue
{
get { return (x & 15 << 4) | (y & 15); }
}
Related
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;
}
I have a byte that represents two values.
First bit represents represents the sequence number.
The rest of the bits represent the actual content.
In C, I could easily parse this out by the following:
typedef struct
{
byte seqNumber : 1;
byte content : 7;
}
MyPacket;
Then I can easily case the input to MyPacket:
char* inputByte = "U"; // binary 01010101
MyPacket * myPacket = (MyPacket*)inputByte;
Then
myPacket->seqNumber = 1
myPacket->content = 42
How can I do the same thing in C#?
Thank you
kab
I would just use properties. Make getters and setters for the two parts that modify the appropriate bits in the true representation.
class myPacket {
public byte packed = 0;
public int seqNumber {
get { return value >> 7; }
set { packed = value << 7 | packed & ~(1 << 7); }
}
public int content {
get { return value & ~(1 << 7); }
set { packed = packed & (1 << 7) | value & ~(1 << 7); }
}
}
C# likes to keep its types simple, so I am betting this is the closest you are getting. Obviously it does not net you the performance improvement in C, but it salvages the meanings.
I am trying to extract the height from a file like this:
http://visibleearth.nasa.gov/view.php?id=73934
The pixels are loaded into an Int32 array
private Int16[] heights;
private int Width, Height;
public TextureData(Texture2D t)
{
Int32[] data = new Int32[t.Width * t.Height];
t.GetData<Int32>(data);
Width = t.Width;
Height = t.Height;
t.Dispose();
heights= new Int16[t.Width * t.Height];
for (int i = 0; i < data.Length; ++i)
{
heights[i] = ReverseBytes(data[i]);
}
}
// reverse byte order (16-bit)
public static Int16 ReverseBytes(Int32 value)
{
return (Int16)( ((value << 8) | (value >> 8)) );
}
I dont know why but the heights are not correct...
I think the Big Endian conversion is wrong, can you help me please?
this is the result, the heights are higher than expected...
http://i.imgur.com/FukdmLF.png
EDIT:
public static int ReverseBytes(int value)
{
int sign = (value & 0x8000) >> 15;
int msb = (value & 0x7F) >> 7;
int lsb = (value & 0xFF) << 8;
return (msb | lsb | sign);
}
is this ok? I don't know why but it is still wrong...
int refers to a 32 bit signed integer but your byte-reverser is written for a 16 bit signed integer so it will only work for positive values up to 32767. If you have any values higher than that you will need to shift and then mask one byte at a time before "orring" them together.
In order to utilize a byte to its fullest potential, I'm attempting to store two unique values into a byte: one in the first four bits and another in the second four bits. However, I've found that, while this practice allows for optimized memory allocation, it makes changing the individual values stored in the byte difficult.
In my code, I want to change the first set of four bits in a byte while maintaining the value of the second four bits in the same byte. While bitwise operations allow me to easily retrieve and manipulate the first four bit values, I'm finding it difficult to concatenate this new value with the second set of four bits in a byte. The question is, how can I erase the first four bits from a byte (or, more accurately, set them all the zero) and add the new set of 4 bits to replace the four bits that were just erased, thus preserving the last 4 bits in a byte while changing the first four?
Here's an example:
// Changes the first four bits in a byte to the parameter value
public void changeFirstFourBits(byte newFirstFour)
{
// If 'newFirstFour' is 0101 in binary, make 'value' 01011111 in binary, changing
// the first four bits but leaving the second four alone.
}
private byte value = 255; // binary: 11111111
Use bitwise AND (&) to clear out the old bits, shift the new bits to the correct position and bitwise OR (|) them together:
value = (value & 0xF) | (newFirstFour << 4);
Here's what happens:
value : abcdefgh
newFirstFour : 0000xyzw
0xF : 00001111
value & 0xF : 0000efgh
newFirstFour << 4 : xyzw0000
(value & 0xF) | (newFirstFour << 4) : xyzwefgh
When I have to do bit-twiddling like this, I make a readonly struct to do it for me. A four-bit integer is called nybble, of course:
struct TwoNybbles
{
private readonly byte b;
public byte High { get { return (byte)(b >> 4); } }
public byte Low { get { return (byte)(b & 0x0F); } {
public TwoNybbles(byte high, byte low)
{
this.b = (byte)((high << 4) | (low & 0x0F));
}
And then add implicit conversions between TwoNybbles and byte. Now you can just treat any byte as having a High and Low byte without putting all that ugly bit twiddling in your mainline code.
You first mask out you the high four bytes using value & 0xF. Then you shift the new bits to the high four bits using newFirstFour << 4 and finally you combine them together using binary or.
public void changeHighFourBits(byte newHighFour)
{
value=(byte)( (value & 0x0F) | (newFirstFour << 4));
}
public void changeLowFourBits(byte newLowFour)
{
value=(byte)( (value & 0xF0) | newLowFour);
}
I'm not really sure what your method there is supposed to do, but here are some methods for you:
void setHigh(ref byte b, byte val) {
b = (b & 0xf) | (val << 4);
}
byte high(byte b) {
return (b & 0xf0) >> 4;
}
void setLow(ref byte b, byte val) {
b = (b & 0xf0) | val;
}
byte low(byte b) {
return b & 0xf;
}
Should be self-explanatory.
public int SplatBit(int Reg, int Val, int ValLen, int Pos)
{
int mask = ((1 << ValLen) - 1) << Pos;
int newv = Val << Pos;
int res = (Reg & ~mask) | newv;
return res;
}
Example:
Reg = 135
Val = 9 (ValLen = 4, because 9 = 1001)
Pos = 2
135 = 10000111
9 = 1001
9 << Pos = 100100
Result = 10100111
A quick look would indicate that a bitwise and can be achieved using the & operator. So to remove the first four bytes you should be able to do:
byte value1=255; //11111111
byte value2=15; //00001111
return value1&value2;
Assuming newVal contains the value you want to store in origVal.
Do this for the 4 least significant bits:
byte origVal = ???;
byte newVal = ???
orig = (origVal & 0xF0) + newVal;
and this for the 4 most significant bits:
byte origVal = ???;
byte newVal = ???
orig = (origVal & 0xF) + (newVal << 4);
I know you asked specifically about clearing out the first four bits, which has been answered several times, but I wanted to point out that if you have two values <= decimal 15, you can combine them into 8 bits simply with this:
public int setBits(int upperFour, int lowerFour)
{
return upperFour << 4 | lowerFour;
}
The result will be xxxxyyyy where
xxxx = upperFour
yyyy = lowerFour
And that is what you seem to be trying to do.
Here's some code, but I think the earlier answers will do it for you. This is just to show some sort of test code to copy and past into a simple console project (the WriteBits method by be of help):
static void Main(string[] args)
{
int b1 = 255;
WriteBits(b1);
int b2 = b1 >> 4;
WriteBits(b2);
int b3 = b1 & ~0xF ;
WriteBits(b3);
// Store 5 in first nibble
int b4 = 5 << 4;
WriteBits(b4);
// Store 8 in second nibble
int b5 = 8;
WriteBits(b5);
// Store 5 and 8 in first and second nibbles
int b6 = 0;
b6 |= (5 << 4) + 8;
WriteBits(b6);
// Store 2 and 4
int b7 = 0;
b7 = StoreFirstNibble(2, b7);
b7 = StoreSecondNibble(4, b7);
WriteBits(b7);
// Read First Nibble
int first = ReadFirstNibble(b7);
WriteBits(first);
// Read Second Nibble
int second = ReadSecondNibble(b7);
WriteBits(second);
}
static int ReadFirstNibble(int storage)
{
return storage >> 4;
}
static int ReadSecondNibble(int storage)
{
return storage &= 0xF;
}
static int StoreFirstNibble(int val, int storage)
{
return storage |= (val << 4);
}
static int StoreSecondNibble(int val, int storage)
{
return storage |= val;
}
static void WriteBits(int b)
{
Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(b),0));
}
}
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