Is there an easy way to convert an array of boolean values into 8-bit hexadecimal equivlents? For example, if I have
bool[] BoolArray = new bool[] { true,false,true,true,false,false,false,true };
If true values=1 and false values=0 then I'd like a method or function that would convert the above array to 0xB1 (10110001).
Does there exist such a function or method to do this? I am using C#, by the way.
Yes, you can use the BitArray class. Something like this should do it:
BitArray arr = new BitArray(BoolArray);
byte[] data = new byte[1];
arr.CopyTo(data, 0);
If by "8-bit hexadecimal" you mean the string representation, you can use the BitConverter class for that:
string hex = BitConverter.ToString(data);
How about
static int BoolArrayToInt(bool[] arr)
{
if (arr.Length > 31)
throw new ApplicationException("too many elements to be converted to a single int");
int val = 0;
for (int i = 0; i < arr.Length; ++i)
if (arr[i]) val |= 1 << i;
return val;
}
static string ToHexStr(int i) { return i.ToString("X8"); }
note: an editor remarked that arr[0] is the LSB but he expected MSB. This is an API consideration, if you prefer your LSB to be at arr[length-1] just reverse the array before passing to that function.
The Binary part can be achieved through this method:
bool[] boolArray = {true, false, true} will give 101:
int BoolArrayToInt(bool[] bArray)
{
char[] caseChar = new char[bArray.Length];
for(int i = 0; i < bArray.Length; i++)
{
if (bArray[i] == true)
{
caseChar[i] = '1';
}
else
{
caseChar[i] = '0';
}
}
string caseString = new string(caseChar);
int caseNum = System.Convert.ToInt32(caseString);
return caseNum;
}
Related
I have array of Bitarray (each element consists of 128 bits) and I want to find duplicate of elements of it.
I tried this code:
Bitarray [] bitsarr=//something;
string g=//convert the array of bitarray to binary string
int numOfBytes = g.Length / 8;
byte[] bytes = new byte[numOfBytes];
for (int i = 0; i < numOfBytes; ++i)
{
bytes[i] = Convert.ToByte(g.Substring(8 * i, 8), 2);
}
int[] bytesAsInts = bytes.Select(x => (int)x).ToArray();
var dict = new Dictionary<int, int>();
foreach (var num in bytesAsInts)
{
if (!dict.ContainsKey(num))
{
dict.Add(num, 0);
}
dict[num]++;
}
foreach (var kvp in dict)
{
Console.WriteLine("{0} repeats {1} times", kvp.Key, kvp.Value);
}
but I don't want to convert it to int because the results will be false.
I want to know the duplication of each element of array of bitarray.
Can anyone help?
You can try to use BitArray.Xor(BitArray) to find duplicates, on MSDN:
The bitwise exclusive OR operation returns true if exactly one operand is true, and returns false if both operands have the same Boolean value
After XOR operation you can check is all bits in BitArray are False:
public static class Extensions
{
public static bool IsAllFalse(this BitArray bitArray)
{
for (int i = 0; i < bitArray.Length; i++)
{
if (bitArray[i] == true)
return false;
}
return true;
}
}
P.S. Mind that BitArray.Xor(BitArray) modifying current object, save values in BitArray object before calling it.
I'm trying to write a program for reversing numbers in binary. For instance, the binary representation of 13 is 1101, and reversing it gives 1011, which corresponds to number 11 right?
Here's my code:
static void Main(string[] args)
{
Console.WriteLine("Enter a Number");
int numb = int.Parse(Console.ReadLine());
int reverse = 0;
while (numb > 0)
{
int rem = numb % 10;
reverse = (reverse * 10) + rem;
numb = numb / 10;
}
Console.WriteLine("Reverse number={0}", reverse);
Console.ReadLine();
}
By this code I only get the numbers to reverse (13 -> 31)...
The input should contain a single line with an integer N, 1≤N≤1000000000 and I want my output in one line with one integer, the number I want to get by reversing the binary representation of N.
Something like that
// 13 = 1101b
int value = 13;
// 11 = 1011b
int result = Convert.ToInt32(new String(
Convert.ToString(value, 2)
.Reverse()
.ToArray()), 2);
Explanation:
Convert.ToString(value, 2) returns value in binary representation ("1101")
Reverse().ToArray() - reverse the string ('1','0','1','1') as sequence of characters and converts to array char[].
new String(...) constructs string "1011" from array of char
finally, Convert.ToInt32(..., 2) convert binary representation back to int
You can use Convert.ToString and Convert.ToInt32 methods, where 2 means binary:
int numb = int.Parse(Console.ReadLine());
var reversedString = Convert.ToString(numb, 2).ReverseString();
var result = Convert.ToInt32(reversedString, 2);
...
public static string ReverseString(this string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
A fun excercise would be doing this without using the string conversion.
I have very little experience with bit twiddling so there is probably a faster and better way of doing this, but this seems to work:
public static IEnumerable<bool> ToBinary(this int n)
{
for (int i = 0; i < 32; i++)
{
yield return (n & (1 << i)) != 0;
}
}
public static int ToInt(this IEnumerable<bool> b)
{
var n = 0;
var counter = 0;
foreach (var i in b.Trim().Take(32))
{
n = n | (i ? 1 : 0) << counter;
counter++
}
return n;
}
private static IEnumerable<bool> Trim(this IEnumerable<bool> list)
{
bool trim = true;
foreach (var i in list)
{
if (i)
{
trim = false;
}
if (!trim)
{
yield return i;
}
}
}
And now you'd call it like this:
var reversed = n.ToBinary().Reverse().ToInt();
In this example, I have to convert the array to a string to use the built in String.Compare method.
char[] array = {'a','b','c'};
string s = "abc";
// here is the extra string allocation
var arrayString = new String(array);
var compareResult = String.Compare(s, arrayString);
Is there an easy way to compare a string to a char array without an extra string allocation?
Note: I need the compare semantics here where I need
"[a] 32-bit signed integer that indicates the lexical relationship between the two comparands."
Less than zero -> strA is less than strB.
Zero -> strA equals strB.
Greater than zero -> strA is greater than strB.
(I'm doing this comparision in loop and I'm generating a lot of extra garbage with the extra string allocation (25-100MB based on the size of my input)_.
I think I will probably end up getting my hands dirty and just writing the code myself.
Try this
int len = Math.Min(array.Length, s.Length);
for (int i = 0; i < len; i++) {
if (s[i] < array[i]) return -1;
if (s[i] > array[i]) return +1;
}
return s.Length.Compare(array.Length);
Strings implement IEnumerable<Char>, so you can loop over them:
for(int i = 0; i < s.Length; i++)
{
// Do comparisons of s.Chars[i] with array[i] as wanted
}
The above will avoid extra string allocations (and assumes that the string length will be the same or larger than the character array length).
You could write an extension method:
public static int Compare(this String str, char[] chars)
{
for (int i = 0; i < str.Length; i++)
if (i == chars.Length)
return 1;
else if (str[i] < chars[i])
return -1;
else if (str[i] > chars[i])
return 1;
if (chars.Length > str.Length)
return -1;
return 0;
}
How about using SequentialEqual?
char[] array = {'a', 'b', 'c'};
string s = "abc";
bool result = array.SequentialEqual(s);
Result is true if they are equal and false if they are different.
I know it does not Compare a the array and the string, it only checks if they are equal. Others have made a better answer to this question.
Okay, here comes my solution based on the solution from #FlyingStreudel and #Olivier Jacot-Descombes:
private void button1_Click(object sender, EventArgs e)
{
char[] array = { 'a', 'b', 'c' };
string s = "abc";
s.Compare(array);
}
...
public static class StringUtils
{
public static int Compare(this String str, char[] chars)
{
if (str == null && chars == null) return 0;
if (str == null) return -1;
if (chars == null) return 1;
int max = Math.Min(str.Length, chars.Length);
for (int i = 0; i < max; i++)
if (str[i] < chars[i])
return -1;
else if (str[i] > chars[i])
return 1;
return str.Length.CompareTo(chars.Length);
}
}
The main difference is that I do not compare i with chars.Length for every char.
Hope this will help you in your quest.
How can I convert BitArray to a single int?
private int getIntFromBitArray(BitArray bitArray)
{
if (bitArray.Length > 32)
throw new ArgumentException("Argument length shall be at most 32 bits.");
int[] array = new int[1];
bitArray.CopyTo(array, 0);
return array[0];
}
private int getIntFromBitArray(BitArray bitArray)
{
int value = 0;
for (int i = 0; i < bitArray.Count; i++)
{
if (bitArray[i])
value += Convert.ToInt16(Math.Pow(2, i));
}
return value;
}
This version:
works for up to 64 bits
doesn't rely on knowledge of BitArray implementation details
doesn't needlessly allocate memory
doesn't throw any exceptions (feel free to add a check if you expect more bits)
should be more than reasonably performant
Implementation:
public static ulong BitArrayToU64(BitArray ba)
{
var len = Math.Min(64, ba.Count);
ulong n = 0;
for (int i = 0; i < len; i++) {
if (ba.Get(i))
n |= 1UL << i;
}
return n;
}
Reffering to this post (#43935747). A value X is short tpe whic I set two bits (6 and 10) like below:
short X=1;
var result = X;
var bitsToSet = new [ ] { 5,9 };
foreach ( var bitToSet in bitsToSet )
{
result+=( short ) Math.Pow ( 2,bitToSet );
}
string binary = Convert.ToString ( result,2 );
Now I would like to read the specific all bits from Value X and put it in to an array or a bit type like bool Val1= bit1, bool Val2=bit2....
I am a newbie and I think it is pretty simple for you guyes..
I've been wondering what the most efficient way to reverse the order of a BitArray in C#. To be clear, I don't want to inverse the Bitarray by calling .Not(), I want to reverse the order of the bits in the array.
Cheers,
Chris
public void Reverse(BitArray array)
{
int length = array.Length;
int mid = (length / 2);
for (int i = 0; i < mid; i++)
{
bool bit = array[i];
array[i] = array[length - i - 1];
array[length - i - 1] = bit;
}
}
For a long array and relative few uses, just wrap it:
class BitArrayReverse
{
private BitArray _ba;
public BitArrayReverse(BitArray ba) { _ba = ba; }
public bool this[int index]
{
get { return _ba[_ba.Length - 1 - index]; }
set { _ba[_ba.Length - 1 - index] = value; }
}
}
This will be the best way
to reverse MSB <-> LSB of any length using XOR in the for loop
public static BitArray BitsReverse(BitArray bits)
{
int len = bits.Count;
BitArray a = new BitArray(bits);
BitArray b = new BitArray(bits);
for (int i = 0, j = len-1; i < len; ++i, --j)
{
a[i] = a[i] ^ b[j];
b[j] = a[i] ^ b[j];
a[i] = a[i] ^ b[j];
}
return a;
}
// in 010000011010000011100b
// out 001110000010110000010b
Dim myBA As New BitArray(4)
myBA(0) = True
myBA(1) = False
myBA(2) = True
myBA(3) = True
Dim myBoolArray1(3) As Boolean
myBA.CopyTo(myBoolArray1, 0)
Array.Reverse(myBoolArray1)
myBA = New BitArray(myBoolArray1)
For a short but inefficient answer:
using System.Linq;
var reversedBa = new BitArray(myBa.Cast<bool>().Reverse().ToArray())
Because the size if fixed at 8-bits just the "table" lookup from below is sufficient -- when dealing with a plain byte a look-up is likely the quickest way. The extra overhead of BitSet to get/set the data may, however, nullify the look-up benefit. Also the initial build cost and persistent overhead need to be considered (but the values could be coded into an array literal ... ick!)
On the other hand, if the data is only 8 bit (ever), and "performance is important", why use a BitArray at all? A BitArray could always be used for the nice features, such as "exploding" to an Enumerable while C# already has decent byte bit manipulation built-in.
Assuming a more general case that the data is 8-bit aligned... but of some undetermined length
Is this actually better (faster, more efficient, etc) than just doing it "per item" in the BitArray? I have no idea but suspect not. I would definitely start with the "simple" methods -- this is here as just a proof-of-concept and may (or may not be) interesting to compare in a benchmark. Anyway, write for clarity first ... and the below is not it! (There is at least one bug in it -- I blame the extra complexity ;-)
byte reverse (byte b) {
byte o = 0;
for (var i = 0; i < 8; i++) {
o <<= 1;
o |= (byte)(b & 1);
b >>= 1;
}
return o;
}
byte[] table;
BitArray reverse8 (BitArray ar) {
if (ar.Count % 8 != 0) {
throw new Exception("no!");
}
byte[] d = new byte[ar.Count / 8];
ar.CopyTo(d, 0);
// this only works if the bit array is
// a multiple of 8. we swap bytes and
// then reverse bits in each byte
int mid = d.Length / 2;
for (int i = 0, j = d.Length - 1; i < mid; i++, j--) {
byte t = d[i];
d[i] = table[d[j]];
d[j] = table[t];
}
return new BitArray(d);
}
string tostr (BitArray x) {
return string.Join("",
x.OfType<bool>().Select(i => i ? "1" : "0").ToArray());
}
void Main()
{
table = Enumerable.Range(0,256).Select(v => reverse((byte)v)).ToArray();
{
byte[] s = new byte[] { 1, 0xff };
BitArray ar = new BitArray(s);
// linqpad :)
tostr(ar).Dump();
tostr(reverse8(ar)).Dump();
}
"--".Dump();
{
byte[] s = new byte[] { 3, 42, 19 };
BitArray ar = new BitArray(s);
// linqpad :)
tostr(ar).Dump();
tostr(reverse8(ar)).Dump();
}
}
Output:
1000000011111111
1111111100000001
--
110000000101010011001000
000100110101010000000011
The expr.Dump() is a LINQPad feature.
Adapted the answer from #TimLoyd and turned it into an extension for easier use.
public static BitArray Reverse(this BitArray array)
{
int length = array.Length;
int mid = (length / 2);
for (int i = 0; i < mid; i++)
{
bool bit = array[i];
array[i] = array[length - i - 1];
array[length - i - 1] = bit;
}
return new BitArray(array);
}
Usage:
var bits = new BitArray(some_bytes).Reverse();