Let's assume we have an array of Boolean values, some are true some are false.
I like to generate a ushort and set the bits according to the array.
A ushort consists of 2 bytes, - that makes up 16 bits.
So the first bool in the array need to set the first bit of the ushort if it's true, otherwise the bit would be 0.
This needs to be repeated for each bit in the ushort.
How would I setup a method stub which takes an array of bools as input and returns the encoded ushort? (C#)
You can make use of the BitConverter class (https://msdn.microsoft.com/en-us/library/bb384066.aspx) in order to convert from bytes to an int, and binary operations (like in this StackOverflow question: How can I convert bits to bytes?) to convert from bits to bytes
For Example:
//Bools to Bytes...
bool[] bools = ...
BitArray a = new BitArray(bools);
byte[] bytes = new byte[a.Length / 8];
a.CopyTo(bytes, 0);
//Bytes to ints
int newInt = BitConverter.ToInt32(bytes); //Change the "32" to however many bits are in your number, like 16 for a short
This will only work for one int, so if you have multiple int's in a single bit array, you'll need to split up the array for this approach to work.
A BitArray might be more suitable for your use case: https://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx
bool[] myBools = new bool[5] { true, false, true, true, false };
BitArray myBA = new BitArray(myBools);
foreach (var value in myBA)
{
if((bool)value == true)
{
}
else
{
}
}
Related
First, I had read many posts and tried BitConverter methods for the conversion, but I haven't got the desired result.
From a 2 byte array of:
byte[] dateArray = new byte[] { 0x07 , 0xE4 };
Y need to get an integer with value 2020. So, the decimal of 0x7E4.
Following method does not returning the desired value,
int i1 = BitConverter.ToInt16(dateArray, 0);
The endianess tells you how numbers are stored on your computer. There are two possibilities: Little endian and big endian.
Big endian means the biggest byte is stored first, i.e. 2020 would become 0x07, 0xE4.
Little endian means the lowest byte is stored first, i.e. 2020 would become 0xE4, 0x07.
Most computers are little endian, hence the other way round a human would expect. With BitConverter.IsLittleEndian, you can check which type of endianess your computer has. Your code would become:
byte[] dateArray = new byte[] { 0x07 , 0xE4 };
if(BitConverter.IsLittleEndian)
{
Array.Reverse(dataArray);
}
int i1 = BitConverter.ToInt16(dateArray, 0);
dateArray[0] << 8 | dateArray[1]
I am using BitConverter.ToInt32 to convert a Byte array into int.
I have only two bytes [0][26], but the function needs 4 bytes, so I have to add two 0 bytes to the front of the existing bytes.
What is the quickest method.
Thank you.
You should probably do (int)BitConverter.ToInt16(..) instead. ToInt16 is made to read two bytes into a short. Then you simply convert that to an int with the cast.
You should call `BitConverter.ToInt16, which only reads two bytes.
short is implicitly convertible to int.
Array.Copy. Here is some code:
byte[] arr = new byte[] { 0x12, 0x34 };
byte[] done = new byte[4];
Array.Copy(arr, 0, done, 2, 2); // http://msdn.microsoft.com/en-us/library/z50k9bft.aspx
int myInt = BitConverter.ToInt32(done); // 0x00000026
However, a call to `BitConverter.ToInt16(byte[]) seems like a better idea, then just save it to an int:
int myInt = BitConverter.ToInt16(...);
Keep in mind endianess however. On little endian machines, { 0x00 0x02 } is actually 512, not 2 (0x0002 is still 2, regardless of endianness).
Which is the fastest way to convert a byte[] to float[] and vice versa (without a loop of course).
I'm using BlockCopy now, but then I need the double memory. I would like some kind of cast.
I need to do this conversion just to send the data through a socket and reconstruct the array in the other end.
Surely msarchet's proposal makes copies too. You are talking about just changing the way .NET thinks about a memory area, if you dont' want to copy.
But, I don't think what you want is possible, as bytes and floats are represented totally different in memory. A byte uses exactly a byte in memory, but a float uses 4 bytes (32 bits).
If you don't have the memory requirements to store your data, just represent the data as the data type you will be using the most in memory, and convert the values you actually use, when you use them.
How do you want to convert a float (which can represent a value between ±1.5 × 10−45 and±3.4 × 10^38) into a byte (which can represent a value between 0 and 255) anyway?
(see more info her about:
byte: http://msdn.microsoft.com/en-us/library/5bdb6693(v=VS.100).aspx
float: http://msdn.microsoft.com/en-us/library/b1e65aza.aspx
More about floating types in .NET here: http://csharpindepth.com/Articles/General/FloatingPoint.aspx
You can use StructLayout to achieve this (from Stack Overflow question C# unsafe value type array to byte array conversions):
[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
[FieldOffset(0)]
public Byte[] Bytes;
[FieldOffset(0)]
public float[] Floats;
}
static void Main(string[] args)
{
// From bytes to floats - works
byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
UnionArray arry = new UnionArray { Bytes = bytes };
for (int i = 0; i < arry.Bytes.Length / 4; i++)
Console.WriteLine(arry.Floats[i]);
}
IEnumerable<float> ToFloats(byte[] bytes)
{
for(int i = 0; i < bytes.Length; i+=4)
yield return BitConverter.ToSingle(bytes, i);
}
Two ways if you have access to LINQ:
var floatarray = ByteArry.AsEnumerable.Cast<float>().ToArray();
or just using Array Functions
var floatarray = Array.ConvertAll(ByteArray, item => (float)item);
I need to store boolean data in Windows Azure. I want to make the space these take up as small as possible. What I have is about fifteen fields with values that are true of false.
field_1 = true;
field_2 = true;
field_a = false;
field_xx = true;
I had an idea that I could take these, convert the true and false to 1s and 0s and then store as a string something like 1101. Is there a simple way that I could do this coding and then uncode when getting the data out? Note that the field names are all different and so I can't use a fancy for loop to go through field names.
int bits = (field_1 ? 1 : 0) | (field_2 ? 2 : 0) | (field_3 ? 4 : 0) | (field_4 ? 8 : 0) | ...
field_1 = (bits & 1) != 0;
field_2 = (bits & 2) != 0;
field_3 = (bits & 4) != 0;
field_4 = (bits & 8) != 0;
...
I don't think you can even imagine how skeptical I am that this will help in any way, shape or form. 15 booleans is literally nothing.
Now, if you insist on going down this path, the best way would be to store them as a single int and use & to read them out and | to write them back in.
You can use a BitArray to pack the booleans into an int:
BitArray b = new BitArray(new bool[] { field_1, field_2, ..., field_xy });
int[] buffer = new int[1];
b.CopyTo(buffer, 0);
int data = buffer[0];
You can use a byte or int array. A byte can hold up to 8 booleans, an int up to 32. To hold up to 16 booleans you could use a byte array with two bytes, or a single int, depending on whether the overhead of an array or the unused bits in the int take up more space. You could also use the BitConverter class to convert a two byte array into a short.
To get the booleans back you create a BitArray from an array of byte or int:
BitArray b = new BitArray(new int[] { data });
field_1 = b[0];
field_2 = b[1];
...
field_xy = b[14];
Consider an enumeration with the [Flags] attribute
[Flags]
public enum Values
{
Field1 = 1,
Field2 = 2,
Field3 = 4,
Field4 = 8
}
Values obj = Field1 | Field2;
obj.HasValue(Field1); //true
obj.HasValue(Field3); //false
int storage = (int)obj;// 3
Don't bother. You're using boolean values, which are already about as small (for an individual value) as you can get (1 byte I believe). And the small amount of space that you might be able to save would not be worth the added complexity of your code, plus the time it would take you to develop it.
A few more thoughts: think how you'd use such a construct. Currently, if you look at field_1 and see a value of true, you don't have to look further into the implementation to figure out the actual value. However, let's say you had the following string: "100101011011010" (or an integer value of 19162, which would be more efficient). Is field_1 true, or is it false? It's not inherently obvious -- you need to go find the implementation. And what happens when you need to support more fields somewhere down the line? You'll save yourself a lot of heartache by sticking with what you've got.
Storing these as characters will take either 8 or 16 bits per value. I'd pack them into the an array of the longest unsigned integer available, using bit-shifting operations.
There is a great post on this at:
http://blog.millermedeiros.com/2010/12/using-integers-to-store-multiple-boolean-values/
You could do this with an int and using xor http://www.dotnetperls.com/xor
I saw a project that did this about 15 years ago. But it ended up with a limitation of 32 roles in the system (it used a 32 bit number). That product does not exist today :)
So do not do it, store values in an array or seperate fields.
you could use Enum with the flags attribute. You say you have 15 fields. So you could try using something like
[Flags]
enum Fieldvals
{
Field1, Field2, ....
}
take a look at http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx for the guidelines
Check out the BitArray class, it should do exactly what you need.
Example:
BitArray bits = new BitArray
(
new bool[]
{
false, true, false, false, true,
false, true, false, true, false,
false, true, false, true, false
}
);
short values = 0;
for( int index = 0; index < bits.Length; index++ )
{
if( bits[ index ] )
values |= ( short )( values | ( 1 << index ) );
}
Console.WriteLine( Convert.ToString( values, 2 ) );
You now have 15 bool variables stored in a single 16 bit field.
You can store your flags in an integer value. Here are some helper methods to accomplish that:
// Sets the given bit position in the UInt32 to the specified boolean value
public static UInt32 Set(UInt32 u, int position, bool newBitValue)
{
UInt32 mask = (UInt32)(1 << position);
if (newBitValue)
return (u | mask)
else
return (u & ~mask);
}
// Gets a bit value from the supplied UInt32
public static bool Get(UInt32 u, int position)
{
return ((u & (UInt32)(1 << position)) != 0);
}
I need to transfrom bits into char array or string, help to find best way to store bits and what shoud I do if for example I have 18 bits I will make 2 char and 2 bits?
The best way to store bits in C# is in the BitArray class, if you just need them as bits. If you need the integer value of the 18 bits, then you have to convert them to int or double or whatever.
First step would be to convert your bit array into bytes and once you have an array of bytes you will need to choose a proper encoding and convert to a string which is an array of chars:
BitArray bitArray = new BitArray(new[] { true, false, true, false, });
byte[] bytes = new byte[bitArray.Length];
bitArray.CopyTo(bytes, 0);
char[] result = Encoding.UTF8.GetString(bytes).ToCharArray();
Obviously you need to know the encoding of those bits in order to be able to convert to characters. If you don't know the encoding you should reconsider what you are trying to do.